/*! bui - v0.0.1 - 2019-07-20 10:07:27 
Copyright (c): kevin.huang  www.vvui.net 
Released under MIT License*/
/**
 * 2019-07-20 解决destroy 相互引用存在的死循环调用问题
 * 2019-07-19 panel组件关闭监听，新增处理关闭前销毁/关闭时间日期，下拉列表的弹窗，完善destroy销毁逻辑,
 * 优化所有组件里面注册到window，body上的事件销毁处理,优化combox下来高度计算
 * 2019-05-16新增jsonViewer
 * 2019-05-14支持window选择输入框
 * 2019-05-12 新增动态表单支持 dyForm
 * 2019-05-03 bindForm 支持calendar时间日期控件
 * ***/
(function (global, factory) {
    if (typeof define === 'function' && define.amd && !window["_all_in_"]) {
        define(['jquery', 'config'], function ($, c) {
            return factory(global, $, c);
        });
    } else {
        factory(global, $);
    }
}(typeof window !== "undefined" ? window : this, function (window, $, cfg) {
    "use strict";
    var $B = window["$B"] ? window["$B"] : {};
    window["$B"] = $B;
    var config = $B.config;
    var document = window.document;
    var charSpan = "<span style='position:absolute;white-space:nowrap;top:-10000000px;left:-10000000px' id='{id}'></span>",
        $body,
        _char_id_ = "__getcharwidth__",
        _ellipsis_char_id = "_ellipsis_char_",
        $spen_CharWidth,
        $ellipsisCharDiv = null,
        loadingHtml = "<div style='padding-left:16px;' class='loading'>" + config.loading + "</div>",
        chars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];


    /**定义一个BaseControl,封装一些共有方法***/
    function BaseControl() {
        this._version = 'bui-0.0.1';
        this._release = '2019-07-20';
        this._author = 'www.vvui.net';
    }
    BaseControl.prototype = {
        constructor: BaseControl,
        version: function () {
            $B.debug(this._version);
            $B.debug(this._release);
            $B.debug(this._author);
        },
        /*** ajax请求
         args={
                async: true,
                url:'',
                data:{},
                ok:function(data,message){},
                fail:function(message){},
                final:function(res){}
        }
        ***/
        ajax: function (args) {
            $B.request(args);
        },
        debug: function (msg) {
            $B.debug(msg);
        },
        error: function (err) {
            $B.debug("error:" + err);
        },
        clear: function () {
            if (this.jqObj) {
                this.jqObj.children().remove();
            }
            this.delProps();
        },
        /**
         * 注册一个函数
         * **/
        regiterFn: function (fnName, fn) {
            this[fnName] = fn;
        },
        /***
         * excuObjName 解决相互引用的 destroy被死循环调用的情况
         * ****/
        destroy: function (excuObjName) {
            if (this.jqObj) {
                this.jqObj.remove();
            }
            this.delProps(excuObjName);
            /***清空继承链***/
            this["__proto__"] = {};
        },
        /***解除所有私有引用***/
        delProps: function (excuObjName) {
            for (var p in this) {
                if (this.hasOwnProperty(p)) {                    
                    if(this[p] !== null && this[p] !== undefined){
                        if( p !== "super" && typeof(this[p].destroy) === "function"){
                            if(!excuObjName || excuObjName !== this[p]){
                                this[p].destroy(this);
                            }
                        }
                    }                    
                    delete this[p];
                }
            }
        }
    };

    function _getBody() {
        if (!$body) {
            $body = $(document.body).css("position", "relative");
        }
        return $body;
    }
    var removeClearTimer;
    var TextEvents = {
        input: function () {
            var $t = $(this);
            if ($t.val() !== "") {
                var $b = _getBody();
                var btn = $b.children("#k_text_clear_btn");
                if (btn.length === 0 || btn.data("target") !== this) {
                    TextEvents.mouseover.call(this);
                }
            }
        },
        mouseover: function () {
            clearTimeout(removeClearTimer);
            var $t = $(this);
            if (!$t.attr("readonly")) {
                var $b = _getBody();
                var clrBtn = $b.children("#k_text_clear_btn").hide();
                if ($t.val() !== "") {
                    var ofs = $t.offset();
                    var left = $t.outerWidth() + ofs.left - 15;
                    var top = ($t.outerHeight() / 2) + ofs.top - 12;
                    if ($t.hasClass("k_combox_input")) {
                        left = left - 18;
                    }
                    if (clrBtn.length === 0) {
                        clrBtn = $("<div id='k_text_clear_btn' style='cursor:pointer;position:absolute;top:" + top + "px;left:" + left + "px;width:14px;height:14px;z-index:2147483647;'><i style='color:#C1C1C1' class='fa fa-cancel-2'></i></div>");
                        clrBtn.appendTo($b).on({
                            click: function () {
                                var $input = $(this).data("target");
                                $input.val("");
                                $input.trigger("input.mvvm");
                                $(this).hide();
                                $input.focus();
                            }
                        }).data("target", $t);
                    } else {
                        clrBtn.data("target", $t).css({ top: top, left: left }).show();
                    }
                }
            }
        },
        mouseout: function (e) {
            var $b = _getBody();
            removeClearTimer = setTimeout(function () {
                $b.children("#k_text_clear_btn").hide();
            }, 800);
        }
    };
    var ajaxOpts = {
        timeout: 2000 * 60,
        type: "POST",
        dataType: 'json',
        async: true,
        error: function (xhr, status, errorThrown) {
            var res = {
                message: config.permission + xhr.status
            };
            try {
                res = eval('(' + xhr.responseText + ')');
            } catch (e) {
                if (window.console) {
                    console.log(xhr.responseText);
                }
            }
            if (xhr.status === 200) {
                this.success(res);
            } else {
                $B.error(config.requestError);
                // if ($body.children("#_request_error_window").length === 0) {
                //     var win = $B.error(res.message);
                //     win.setAttr({
                //         "id": "_request_error_window"
                //     });
                // }
            }
            this.recoverButton();
            this.final(status);
        },
        success: function (res) {
            this.recoverButton();
            this.final(res);
            if (typeof res.code !== "undefined") {
                if (res.code === 0) {
                    var data = res.data;
                    if (res.strConvert) {
                        data = eval('(' + res.data + ')');
                    }
                    this.ok(res.message, data, res);
                } else if (res.code === 99999) {
                    if (res.data === "notlogin") {
                        $B.error(res.message);
                        setTimeout(function () {
                            if (window.ctxPath) {
                                window.top.location = $B.getHttpHost(window.ctxPath);
                            }
                        }, 1600);
                    } else {
                        $B.error(config.permission);
                    }
                } else {
                    this.fail(res.message, res);
                }
            } else {
                this.ok(res, res);
            }
        },
        /**
         *当返回结果是正确时的处理
         *data:返回的数据
         *message:提示的信息
         **/
        ok: function (message, data) { },
        recoverButton: function () {
            if (this["target"]) {
                this["target"].removeAttr("disabled");
                if (this["target"][0].tagName === "INPUT") {
                    this["target"].val(this.recoverText);
                } else {
                    this["target"].html(this.recoverText);
                }
                this["target"] = undefined;
            }
        },
        /***
         *当返回结果是非正确时的处理
         ***/
        fail: function (msg, res) {
            if (_getBody().children("#_request_fail_window").length === 0) {
                var win = $B.alert(msg);
                win.setAttr({
                    "id": "_request_fail_window"
                });
            }
        },
        /**
         * 无论如何都回调的函数
         ****/
        final: function (res) { //无论成功，失败，错误都执行的回调
        }
    };
    /****原生扩展******/
    //-------------------------------------
    //十六进制颜色值的正则表达式
    var reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
    /*RGB颜色转换为16进制*/
    String.prototype.toHexColor = function () {
        var that = this;
        if (/^(rgb|RGB)/.test(that)) {
            var aColor = that.replace(/(?:\(|\)|rgb|RGB)*/g, "").split(",");
            var strHex = "#";
            for (var i = 0; i < aColor.length; i++) {
                var hex = Number(aColor[i]).toString(16);
                if (hex.length === 1) {
                    hex = "0" + hex;
                }
                if (hex === "0") {
                    hex += hex;
                }
                strHex += hex;
            }
            if (strHex.length !== 7) {
                strHex = that;
            }
            return strHex.toUpperCase();
        } else if (reg.test(that)) {
            var aNum = that.replace(/#/, "").split("");
            if (aNum.length === 6) {
                return that.toUpperCase();
            } else if (aNum.length === 3) {
                var numHex = "#";
                for (var j = 0; j < aNum.length; j += 1) {
                    numHex += (aNum[j] + aNum[j]);
                }
                return numHex.toUpperCase();
            }
        } else {
            return that.toUpperCase();
        }
    };
    //-------------------------------------------------
    /*16进制颜色转为RGB格式*/
    String.prototype.toRgbColor = function () {
        var sColor = this.toLowerCase();
        if (sColor && reg.test(sColor)) {
            if (sColor.length === 4) {
                var sColorNew = "#";
                for (var i = 1; i < 4; i += 1) {
                    sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1));
                }
                sColor = sColorNew;
            }
            //处理六位的颜色值
            var sColorChange = [];
            for (var j = 1; j < 7; j += 2) {
                sColorChange.push(parseInt("0x" + sColor.slice(j, j + 2)));
            }
            return "RGB(" + sColorChange.join(",") + ")";
        } else {
            return sColor.toUpperCase();
        }
    };
    Array.prototype.unique = function () {
        this.sort();
        var re = [this[0]];
        for (var i = 1; i < this.length; i++) {
            if (this[i] !== re[re.length - 1]) {
                re.push(this[i]);
            }
        }
        return re;
    };
    Date.prototype.format = function (format) {
        var date = {
            "M+": this.getMonth() + 1,
            "d+": this.getDate(),
            "h+": this.getHours(),
            "m+": this.getMinutes(),
            "s+": this.getSeconds(),
            "q+": Math.floor((this.getMonth() + 3) / 3),
            "S+": this.getMilliseconds()
        };
        if (/(y+)/i.test(format)) {
            format = format.replace(RegExp.$1, (this.getFullYear() + '').substr(4 - RegExp.$1.length));
        }
        for (var k in date) {
            if (new RegExp("(" + k + ")").test(format)) {
                format = format.replace(RegExp.$1, RegExp.$1.length === 1 ? date[k] : ("00" + date[k]).substr(("" + date[k]).length));
            }
        }
        return format;
    };
    String.prototype.trim = function () {
        return this.replace(/(^\s*)|(\s*$)/g, "");
    };
    String.prototype.leftTrim = function () {
        return this.replace(/(^\s*)/g, "");
    };
    String.prototype.rightTrim = function () {
        return this.replace(/(\s*$)/g, "");
    };
    /**HashTable**/
    function HashTable() {
        this.size = 0;
        this.entry = {};
        var i, len, attr;
        if (typeof this.add !== 'function') {
            HashTable.prototype.add = function (key, value) {
                if (!this.containsKey(key)) {
                    this.size++;
                }
                this.entry[key] = value;
            };
        }
        if (typeof this.getValue !== 'function') {
            HashTable.prototype.getValue = function (key) {
                return this.containsKey(key) ? this.entry[key] : null;
            };
        }
        if (typeof this.remove !== 'function') {
            HashTable.prototype.remove = function (key) {
                if (this.containsKey(key) && (delete this.entry[key])) {
                    this.size--;
                }
            };
        }
        if (typeof this.containsKey !== 'function') {
            HashTable.prototype.containsKey = function (key) {
                return (key in this.entry);
            };
        }
        if (typeof this.containsValue !== 'function') {
            HashTable.prototype.containsValue = function (value) {
                var pkeys = Object.keys(this.entry);
                for (i = 0, len = pkeys.length; i < len; ++i) {
                    attr = pkeys[i];
                    if (this.entry[attr] === value) {
                        return true;
                    }
                }
                return false;
            };
        }
        if (typeof this.getValues !== 'function') {
            HashTable.prototype.getValues = function () {
                var values = [];
                var pkeys = Object.keys(this.entry);
                for (i = 0, len = pkeys.length; i < len; ++i) {
                    attr = pkeys[i];
                    values.push(this.entry[attr]);
                }
                return values;
            };
        }
        if (typeof this.getKeys !== 'function') {
            HashTable.prototype.getKeys = function () {
                var keys = Object.keys(this.entry);
                return keys;
            };
        }
        if (typeof this.getSize !== 'function') {
            HashTable.prototype.getSize = function () {
                return this.size;
            };
        }
        if (typeof this.clear !== 'function') {
            HashTable.prototype.clear = function () {
                this.size = 0;
                this.entry = {};
            };
        }
        if (typeof this.joinValue !== 'function') {
            HashTable.prototype.joinValue = function (key, value, split) {
                var sp = typeof split === 'undefined' ? ',' : split;
                var existValue = this.getValue(key);
                if (existValue === null) {
                    this.add(key, value);
                    this.size++;
                } else {
                    var arr = existValue.split(sp);
                    arr.push(value);
                    this.add(key, arr.join(sp));
                }
            };
        }
        if (typeof this.destroy !== 'function') {
            HashTable.prototype.destroy = function () {
                this.size = 0;
                this.entry = null;
            };
        }
        if (typeof this.each !== 'function') {
            HashTable.prototype.each = function (fn) {
                var pkeys = Object.keys(this.entry);
                for (i = 0, len = pkeys.length; i < len; ++i) {
                    attr = pkeys[i];
                    fn(attr, this.entry[attr]);
                }
            };
        }
        if (typeof this.getJson !== 'function') {
            HashTable.prototype.getJson = function (fn) {
                return $.extend(true, {}, this.entry);
            };
        }
    }
    $B["HashTable"] = HashTable;

    /**静态API**/
    $.extend($B, {
        /**框架的ajax统一入口
         *所有ajax返回均以 res={code:'',message:'',data:{}}的格式返回
        *code=0表示服务器无异常运行并返回结果，code=1时，表示服务器出现异常并返回提示
        *message，用与服务器返回的信息提示
        *data,用于服务器返回的数据，如tree组件、datagrid组件返回的数据就保存到data当中
        args={
                timeout: 1000 * 60, //超时
                type: "POST",       //请求方式
                dataType: 'json',   //请求数据类型
                async: true,        //是否异步
                preRequest: fn,     //请求前，回调
                url:'',             //请求url
                data:{},            //请求参数
                ok:function(message,data){},    //成功回调，message:返回信息，data:返回数据
                fail:function(message){},       //失败回调，message:返回信息
                final:function(res){}           //无论成功/失败都调用的回调 res = {code:'',message:'',data:{}}
        }
        ****/
        request: function () {
            var args = arguments[0];
            var opts;
            if (args !== undefined) {
                opts = $.extend({}, ajaxOpts, args);
            } else {
                opts = ajaxOpts;
            }
            if (typeof opts.preRequest === 'function') {
                opts.preRequest();
            }
            //剔除值为null的参数，null表示不需要更新到数据库
            for (var prop in opts.data) {
                if (opts.data[prop] === null) {
                    delete opts.data[prop];
                } else {
                    opts.data[prop] = this.htmlEncode(opts.data[prop]);
                    //opts.data[prop] = opts.data[prop];
                }
            }
            var queue = window["_submit_queues"];
            var submitBtn;
            if (queue && queue.length > 0) {
                var lastIdx = queue.length - 1;
                var diff = queue[lastIdx].date - new Date();
                if (diff <= 500) {//500毫秒内
                    submitBtn = queue[lastIdx].btn;
                    var q = queue.shift();
                    q.btn = undefined;
                }
            }
            if (arguments.length > 1 || submitBtn) {
                var btn = arguments.length > 1 ? arguments[1] : submitBtn;
                opts["target"] = btn;
                btn.attr("disabled", "disabled");
                if (btn[0].tagName === "INPUT") {
                    opts["recoverText"] = btn.val();
                    btn.val(config.busy);
                } else {
                    opts["recoverText"] = btn.html();
                    btn.html(config.busy);
                    btn.prepend("<i style='padding:0;margin-right:3px;' class='fa fa-spin fa-spin6'></i>");
                }
            }
            $.ajax(opts);
        },
        /***
         * 深色、浅色换转 
         * col 16进制颜色
         * amt自定义变暗参数，< 0为变暗，>0为变亮
         * ***/
        lightenDarkenColor: function (col, amt) {
            var usePound = false;
            if (col[0] === "#") {
                col = col.slice(1);
                usePound = true;
            }
            var num = parseInt(col, 16);
            var r = (num >> 16) + amt;
            if (r > 255) {
                r = 255;
            } else if (r < 0) {
                r = 0;
            }
            var b = ((num >> 8) & 0x00FF) + amt;
            if (b > 255) {
                b = 255;
            } else if (b < 0) {
                b = 0;
            }
            var g = (num & 0x0000FF) + amt;
            if (g > 255) {
                g = 255;
            } else if (g < 0) {
                g = 0;
            }
            return (usePound ? "#" : "") + String("000000" + (g | (b << 8) | (r << 16)).toString(16)).slice(-6);
        },
        /**
         * 判断颜色是否是浅色，深色
         * ***/
        isContrastYIQ: function (_color) {
            var colorrgb = _color;
            if (_color.indexOf("#") > -1) {
                colorrgb = _color.toRgbColor(); //colorRgb(hexcolor);
            }
            var colors = colorrgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
            var red = colors[1];
            var green = colors[2];
            var blue = colors[3];
            var brightness;
            brightness = (red * 299) + (green * 587) + (blue * 114);
            brightness = brightness / 255000;
            if (brightness >= 0.5) {
                return "light";
            } else {
                return "dark";
            }
        },
        /**
         * 用于提交期间，改变按钮的状态，防止重复提交
         * ***/
        changeButtonStatus: function (button) {
            var i = button.children("i");
            var clazz;
            if (button.attr("disabled")) {
                button.removeAttr("disabled");
                clazz = button.data("clazz");
                button.removeData("clazz").removeClass("k_toolbar_button_disabled");
                i.attr("class", clazz);
            } else {
                button.prop("disabled", true);
                clazz = i.attr("class");
                button.data("clazz", clazz).addClass("k_toolbar_button_disabled");
                i.attr("class", "fa fa-spin6 fa-spin");
            }
        },
        getHttpHost: function (ctxPath) {
            var proto = window.location.protocol;
            var host = proto + "//" + window.location.host;
            var ctx;
            if (!ctxPath && window.ctxPath) {
                ctx = window.ctxPath;
            } else if (ctxPath) {
                ctx = ctxPath;
            }
            if (ctx) {
                host = host + ctx;
            }
            return host;
        },
        htmlEncode: function (str) {
            if (!str || typeof str.replace === "undefined") {
                return str;
            }
            var s = "";
            if (str.length === 0) {
                return "";
            }
            // s = str.replace(/&/g,"&amp;");
            s = str.replace(/</g, "&lt;");
            s = s.replace(/>/g, "&gt;");
            s = s.replace(/eval\((.*)\)/g, "");
            s = s.replace(/<.*script.*>/, "");
            /*双引号 单引号不替换
            s = s.replace(/\'/g,"&#39;");
            s = s.replace(/\"/g,"&quot;");*/
            return s;
        },
        htmlDecode: function (str) {
            if (typeof str.replace === "undefined") {
                return str;
            }
            var s = "";
            if (str.length === 0) {
                return "";
            }
            s = str.replace(/&amp;/g, "&");
            s = s.replace(/&lt;/g, "<");
            s = s.replace(/&gt;/g, ">");
            s = s.replace(/&#39;/g, "\'");
            s = s.replace(/&quot;/g, "\"");
            return s;
        },
        /**获取元素旋转后的位置偏移量**/
        getAnglePositionOffset: function (el) {
            var matrix = el.css("transform");
            var ofs = { fixTop: 0, fixLeft: 0 };
            if (matrix && matrix !== "none") {
                var pos = el.position();
                var angle = $B.getMatrixAngle(matrix);
                if (angle !== 0) {
                    var clone = $("<div />");
                    var style = el.attr("style");
                    clone.attr("style", style).css({ "filter": "alpha(opacity=0)", "-moz-opacity": "0", "opacity": "0", "position": "absolute", "z-index": -111 });
                    clone.css("transform", "rotate(0deg)");
                    clone.appendTo(el.parent());
                    var clonePos = clone.position();
                    ofs.fixTop = clonePos.top - pos.top;
                    ofs.fixLeft = -(pos.left - clonePos.left);
                    clone.remove();
                }
            }
            return ofs;
        },
        /**
         * 获取旋转的角度
         * matrix = css("transform")
         * **/
        getMatrixAngle: function (matrix) {
            if (matrix === "none") {
                return 0;
            }
            var values = matrix.split('(')[1].split(')')[0].split(',');
            var a = values[0];
            var b = values[1];
            var angle = Math.round(Math.atan2(b, a) * (180 / Math.PI));
            return angle;
        },
        /**
         * debug日志
         * ***/
        debug: function (message) {
            console.log("debug:" + message);
        },
        /**
         * 继承实现，child子类，parent父类，parent不传则默认为baseControl
         * _this 子类this, 
         * child 子类构造函数, 
         * parent 需要继承的父类构造函数,
         * args 参数
         * ****/
        extend: function (_this, child, parent, args) {
            if (!parent) {
                parent = BaseControl;
            }
            /***私有继承***/
            parent.call(_this, args);
            /***拷贝prototype继承***/
            Object.keys(parent.prototype).forEach(function (key) {
                var prop = child.prototype[key];
                if (!prop) { //如果子类已经存在，则不继承,模拟重写
                    child.prototype[key] = parent.prototype[key];
                }
            });
            child.prototype.constructor = child;
            //开放子类调用基类
            _this["super"] = new parent();
        },
        scrollbar: function (_this) {
            if (_this.mCustomScrollbar) {

            } else {
                _this.css("overflow", "auto");
            }
        },
        /**获取一个HashTable**/
        getHashTable: function () {
            return new HashTable();
        },
        /**是否是url**/
        isUrl: function (str) {
            return /^((http(s)?|ftp):\/\/)?([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?(:\d+)?/.test(str);
        },
        /***
         * 写cookie
         * ***/
        writeCookie: function (name, value, expiredays) {
            if (!this.isNotEmpty(expiredays)) {
                expiredays = 1;
            }
            try {
                var exdate = new Date();
                exdate.setDate(exdate.getDate() + expiredays);
                document.cookie = name + "=" + window.escape(value) + ";expires=" + exdate.toGMTString();
            } catch (ex) {
            }
        },
        /**
         * 读取cookie
         * ***/
        getCookie: function (c_name) {
            if (document.cookie.length > 0) {
                var c_start = document.cookie.indexOf(c_name + "=");
                if (c_start !== -1) {
                    c_start = c_start + c_name.length + 1;
                    var c_end = document.cookie.indexOf(";", c_start);
                    if (c_end === -1) {
                        c_end = document.cookie.length;
                    }
                    return window.unescape(document.cookie.substring(c_start, c_end));
                }
            }
            return "";
        },
        isIE: function () {
            var userAgent = navigator.userAgent.toLowerCase();
            return userAgent.indexOf("rv:11.0") > 0 || /msie/.test(userAgent);
        },
        isNotEmpty: function (v) {
            return v !== null && typeof v !== 'undefiend' && v !== "";
        },
        /**获取滚动条宽度**/
        getScrollWidth: function () {
            var noScroll, scroll, oDiv = document.createElement("DIV");
            oDiv.style.cssText = "position:absolute; top:-1000px; width:100px; height:100px; overflow:hidden;";
            noScroll = document.body.appendChild(oDiv).clientWidth;
            oDiv.style.overflowY = "scroll";
            scroll = oDiv.clientWidth;
            document.body.removeChild(oDiv);
            return noScroll - scroll;
        },
        /***
         * 创建高性能的延时运行函数（避免频繁执行）
         * func:需要延时运行的函数
         * wait:等待时间 毫秒
         * immediate:是否立即执行
         * 返回一个执行函数
         * ***/
        delayFun: function (func, wait, immediate) {
            var timeout;
            return function () {
                var context = this,
                    args = arguments;
                var later = function () {
                    timeout = null;
                    if (!immediate) {
                        func.apply(context, args);
                    }
                };
                var callNow = immediate && !timeout;
                clearTimeout(timeout);
                timeout = setTimeout(later, wait);
                if (callNow) {
                    func.apply(context, args);
                }
            };
        },
        /***
         * 对一个tag标签定义一个信息提示框
         * target:目标标签
         * message:提示的信息
         * timeout:自动消失时间，可以不填
         * return 返回提示框对象本身，可以需要关闭可以用 returnObj.hide() / returnObj.show() /returnObj.remove()
         * ***/
        tagMessage: function (target, message, timeout) { },
        /**
         * 获取当前url中参数，并以对象形式返回
         * @param strUrl 需要获取的url，如果不传则为当前打开页面的url
         * ***/
        getUrlParams: function (strUrl) {
            var url;
            if (strUrl !== undefined) {
                url = strUrl;
            } else {
                url = location.search;
            }
            var params = {};
            var index = url.indexOf("?");
            if (index !== -1) {
                var str = url.substr(index + 1);
                var strs = str.split("&");
                for (var i = 0; i < strs.length; i++) {
                    params[strs[i].split("=")[0]] = unescape(strs[i].split("=")[1]);
                }

            }
            /** 
            var obj = {};            
            var params = window.location.search.substr(1);
            //[^&=]+ 表示不含&或=的连续字符，加上()就是提取对应字符串
            url.replace(/([^&=]+)=([^&=]*)/gi,function(rs,$1,$2){
                obj[$1] =  decodeURIComponent($2);
            });
            return obj;
            **/
            return params;
        },
        /***
         * 获取当前鼠标的位置
         ***/
        mouseCoords: function (ev) {
            if (ev.pageX || ev.pageY) {
                return {
                    x: ev.pageX,
                    y: ev.pageY
                };
            } else {
                return {
                    x: ev.clientX + document.body.scrollLeft - document.body.clientLeft,
                    y: ev.clientY + document.body.scrollTop - document.body.clientTop
                };
            }
        },
        getEllipsisChar: function (txt, fs, width, height) {
            if ($ellipsisCharDiv === null) {
                $ellipsisCharDiv = _getBody().children("#" + _ellipsis_char_id);
                if ($ellipsisCharDiv.length === 0) {
                    $ellipsisCharDiv = $("<div style='height:" + height + "px;width:" + width + "px;position:absolute;top:0;z-index:0;overflow:auto;top:-1000px;' id='" + _ellipsis_char_id + "'></div>").appendTo(_getBody());
                }
            }
            $ellipsisCharDiv.css("font-size", fs).html("");
            var len = txt.length,
                i = 0;
            var el = $ellipsisCharDiv[0];
            for (; i < len; i++) {
                el.innerHTML = txt.substr(0, i);
                if (el.scrollHeight > height) {
                    el.innerHTML = txt.substr(0, i - 2);
                    break;
                }
            }
            return el.innerHTML + "...";
        },
        /***
         *获取字符长度
         *@param text 文本
         *@param fs 文本的字体大小
         **/
        getCharWidth: function (text, fs) {
            if (typeof fs === 'undefined') {
                fs = $B.config.fontSize;
            }
            if (!$spen_CharWidth) {
                $spen_CharWidth = $(charSpan.replace(/{id}/, _char_id_)).appendTo(_getBody());
            }
            $spen_CharWidth.css({
                'font-size': fs
            });
            var w = 20;
            try {
                $spen_CharWidth.html(this.htmlEncode(text));
                w = $spen_CharWidth.outerWidth();
                setTimeout(function () {
                    $spen_CharWidth.html("");
                }, 1);
            } catch (ex) {
                this.error(ex);
            }
            return w;
        },
        getUUID: function () {
            return this.generateDateUUID();
        },
        generateDateUUID: function (fmt, count) {
            var c = count ? count : 12;
            var formt = fmt ? fmt : "yyyyMMddhhmmss";
            var prex = (new Date()).format(formt);
            return prex + this.generateMixed(c);
        },
        /***产生混合随机数
         *@param n 位数 默认6
         ***/
        generateMixed: function (n) {
            var _n = n ? n : 6;
            var res = [];
            for (var i = 0; i < _n; i++) {
                var id = Math.ceil(Math.random() * 35);
                res.push(chars[id]);
            }
            return res.join("");
        },
        /*** 某个html标签加载远程html文件
         options={  target:jquery目标对象,
                    url:'远程地址',
                    params:{},//参数
                    preload:function(){.........} , //加载前处理事件
                    onLoaded:function(result){.........}  //加载后处理事件
        } ***/
        htmlLoad: function () {
            var opts = arguments[0];
            opts.target.children().remove();
            opts.target.html(loadingHtml);
            if (typeof opts.preload === 'function') {
                opts.preload.call(opts.target);
            }
            var url = opts.url;
            if (url.indexOf("?") > 0) {
                url = url + "&_c_1=" + this.generateMixed(5);
            } else {
                url = url + "?_c_1=" + this.generateMixed(5);
            }
            opts.target.load(url, opts.params, function (xmlReq, statu, error) {
                if (statu === 'error') {
                    if (xmlReq) {
                        var re = new RegExp("<body>(.+)</body>", "gi");
                        var res = re.exec(xmlReq);
                        if (res.length >= 2) {
                            opts.target.html(res[1]);
                        } else {
                            opts.target.html(xmlReq);
                        }
                    } else {
                        var addr = $B.getHttpHost();
                        if (addr.indexOf("file:") >= 0) {
                            opts.target.html($B.config.crossError);
                        } else {
                            opts.target.html($B.config.htmlLoadError);
                        }
                    }
                } else {
                    if (typeof opts.onLoaded === 'function') {
                        opts.onLoaded.call(opts.target);
                    }
                }
            });
        },
        /**获取jquery对象
         * idOrTag
         * ***/
        getJqObject: function (idOrTag) {
            if (typeof idOrTag === 'string') {
                return $(idOrTag);
            } else {
                return idOrTag;
            }
        },
        /**
         *将form表单转为json对象
         *@param form 表单的容器如div、table、form
         *@param entityJson 实体json
         ***/
        parseForm: function (form, entityJson) {
            var _this = this;
            var formWrap = this.getJqObject(form);
            function objectToKeyValuePair($obj, _hash) {
                var _key = $obj.attr("id");
                if (!_key) {
                    _key = $obj.attr("name");
                }
                if (_key !== undefined) {
                    var _val = $obj.val();
                    _hash.add(_key, _val);
                    return _key + '=' + _val; //返回值，如果需要的话
                } else {
                    return null;
                }
            }
            var allText = formWrap.find("input[type=text]");
            var allPwdText = formWrap.find("input[type=password]");
            var allAreatext = formWrap.find("textarea");
            var allRadio = formWrap.find("input[type=radio]");
            var allCheckbox = formWrap.find("input[type=checkbox]");
            var allSelect = formWrap.find("select");
            var allHidden = formWrap.find("input[type=hidden]");
            var allFileText = formWrap.find("input[type=file]");
            var hash = this.getHashTable();
            //所有隐藏域
            $.each(allHidden, function (idx, obj) {
                objectToKeyValuePair($(obj), hash);
            });
            //所有密码框
            $.each(allPwdText, function (idx, obj) {
                objectToKeyValuePair($(obj), hash);
            });
            //查找所有文本框
            $.each(allText, function (idx, obj) {
                objectToKeyValuePair($(obj), hash);
            });
            //查找所有文件框
            $.each(allFileText, function (idx, obj) {
                objectToKeyValuePair($(obj), hash);
            });
            //查找所有多行文本
            $.each(allAreatext, function (idx, obj) {
                objectToKeyValuePair($(obj), hash);
            });
            /*****Radio******/
            $.each(allRadio, function (idx, obj) {
                hash.add($(obj).attr("name"), null); //先加键，value设空
            });
            $.each(allRadio, function (idx, obj) {
                var $t = $(obj);
                if ($t.is(":checked")) {
                    hash.joinValue($t.attr("name"), $t.val()); //设置值
                }
            });
            /*****Checkbox存在多选情况******/
            if (allCheckbox.length > 0) {
                var tempData = {};
                $.each(allCheckbox, function (idx, obj) {
                    var $obj = $(obj);
                    var _n = $obj.attr("name");
                    if (!tempData[_n]) {
                        tempData[_n] = []; //先加键，value设空
                    }
                    if ($obj.is(":checked")) {
                        tempData[_n].push($obj.val());
                    }
                });
                for (var key in tempData) {
                    if (this.hasOwnProperty(key)) {
                        var _v = tempData[key].join(',');
                        if (_v !== '') {
                            hash.add(key, _v); //设置值
                        }
                    }
                }
            }
            //查找所有下拉列表
            $.each(allSelect, function (idx, obj) {
                var $t = $(obj);
                if ($t.attr("multiple") === true) {
                    var allvalue = [];
                    hash.add($t.attr("name"), ''); //先加键，value设空
                    var sels = $t.children("option[selected]");
                    $.each(sels, function (j, o) {
                        allvalue.push($(o).value);
                    });
                    hash.joinValue($t.attr("name"), allvalue.join(',')); //设置值
                } else {
                    objectToKeyValuePair($t, hash);
                }
            });
            var objJson = hash.getJson();
            hash.destroy();
            if (entityJson) {
                return $.extend(true, {}, entityJson, objJson);
            } else {
                return objJson;
            }
        },
        /***实现双向绑定的表单填充
         *@param form 待填充的表单，如table、form
         *@param dataObj 填充数据，JSON对象
         *@param onchangeFn 
         *@return:返回具有双向联动能力的数据对象
         ***/
        bindForm: function (form, dataObj, onchangeFn) {
            var copyData = dataObj;//$.extend(true,{},dataObj);
            var oldFiledMap = {};
            if ($B.Mvvm) {
                var allText = form.find("input[type=text]");
                var bindExpressFn = function ($tag, setExprssFn) {
                    var prop = $tag.attr("id");
                    if (!prop) {
                        prop = $tag.attr("name");
                    }
                    if (typeof dataObj[prop] !== "undefined") {
                        setExprssFn($tag, prop);
                    }
                    //处理新旧验证
                    if (prop.indexOf("old_") === 0) {
                        var srProp = prop.replace("old_", "");
                        var v = dataObj[srProp];
                        $tag.val(v);
                        oldFiledMap[prop] = v;
                    }
                };
                allText.each(function () {
                    var $txt = $(this);
                    bindExpressFn($txt, function ($tag, prop) {
                        if ($tag.hasClass("k_combox_input")) {//对combox进行默认支持
                            $tag.attr("watcher", "kcomboxWatcher").attr("express", "{{this.kcomboxExpress(this.data." + prop + ",el)}}");
                        } else if ($tag.hasClass("k_calendar_input")) {//2019-05-03对时间日期控件进行支持
                            $tag.attr("watcher", "kcalendarWatcher").attr("express", "{{this.kcalendarExpress(this.data." + prop + ",el)}}");
                        }else if($tag.hasClass("k_window_input")){ //   2019-05-14支持window选择输入框
                            $tag.attr("watcher", "kwindowInputWatcher").attr("express", "{{this.kwindowInputExpress(this.data." + prop + ",el)}}");
                        } else {
                            $tag.attr("value", "{{this.data." + prop + "}}");
                        }
                    });
                });
                var allPwdText = form.find("input[type=password]");
                allPwdText.each(function () {
                    var $txt = $(this);
                    bindExpressFn($txt, function ($tag, prop) {
                        $tag.attr("value", "{{this.data." + prop + "}}");
                    });
                });

                var allHidden = form.find("input[type=hidden]");
                allHidden.each(function () {
                    var $txt = $(this);
                    bindExpressFn($txt, function ($tag, prop) {
                        $tag.attr("value", "{{this.data." + prop + "}}");
                    });
                });

                var allAreatext = form.find("textarea");
                allAreatext.each(function () {
                    var $txt = $(this);
                    bindExpressFn($txt, function ($tag, prop) {
                        $tag.text("{{this.data." + prop + "}}");
                    });
                });
                var allRadio = form.find("input[type=radio]");
                allRadio.each(function () {
                    var r = $(this);
                    var name = r.attr("name");
                    var $label = r.parent();
                    if ($label.hasClass("k_radio_label") && typeof dataObj[name] !== "undefined") {
                        $label.attr("watcher", "kRadioWatcher").attr("express", "{{this.kRadioExpress(this.data." + name + ",el)}}");
                    }
                });

                var allCheckbox = form.find("input[type=checkbox]");
                allCheckbox.each(function () {
                    var r = $(this);
                    var name = r.attr("name");
                    var $label = r.parent();
                    if ($label.hasClass("k_checkbox_label") && typeof dataObj[name] !== "undefined") {
                        $label.attr("watcher", "kcheckBoxWatcher").attr("express", "{{this.kcheckBoxExpress(this.data." + name + ",el)}}");
                    }
                });

                var allSelect = form.find("select");
                allSelect.each(function () {
                    var $ele = $(this);
                    var id = $ele.attr("id");
                    if (dataObj[id]) {
                        var optsHtml = [];
                        $ele.children().each(function () {
                            var opt = $(this);
                            var v = opt.val();
                            var txt = opt.text();
                            var sle = "{{this.data." + id + " === '" + v + "' ? true:false}}";
                            var optHtml = '<option value="' + v + '" selected="' + sle + '">' + txt + '</option>';
                            optsHtml.push(optHtml);
                        });
                        $ele.html(optsHtml.join(""));
                    }
                });
                //var allFileText = form.find("input[type=file]");
                //树形控件支持
                form.find("ul.k_tree_root").each(function () {
                    bindExpressFn($(this), function ($tag, prop) {
                        $tag.attr("watcher", "ktreeWatcher").attr("express", "{{this.ktreeExpress(this.data." + prop + ",el)}}");
                    });
                });
                var vm = new $B.Mvvm({
                    el: form[0],
                    data: copyData,
                    onChanged: onchangeFn,
                    onGetJson: function (json) {
                        $.extend(json, oldFiledMap);
                    }
                });
                window["curMvvm"] = vm;
                return vm;
            }else{
                console.log("没有加载mvvm组件");
            }
        },
        /***
         *将json对象填充到容器中，与bindForm有区别，fillView只是将内容填充到对应的区域
         *这里填充的是任意元素，常用于填充到详情显示页面
         *@param wrap 待填充的容器对象
         *@param dataObj 填充数据，JSON对象
         ***/
        fillView: function (wrap, dataObj) {
            for (var attr in dataObj) {
                if (this.hasOwnProperty(attr)) {
                    var value = dataObj[attr];
                    if (value === null || value === undefined) {
                        value = "";
                    }
                    var $html = wrap.find("#" + attr);
                    if ($html.length > 0) {
                        if ($html[0].tagName === 'INPUT') {
                            $html.value(value);
                        } else {
                            $html.text(value);
                        }
                    }
                }
            }
        },
        /***
         *重置表单
         *@param form 需要重置的表单元素外包对象
         *@param defData 重置表单时候的默认数据，如果某个元素没有传默认值，则为空
         *defData 可以不传
         ****/
        resetForm: function (form, defData) {
        },
        /**
        * 简单下拉列表（原生的select）
         options={
             target:id/对象,
             data:option数据项,
             idField:'option的value字段',	
             textField:'option显示的字段',	
             defaultVal:'选择的项目的值',	  	
             onchange:fn(选择的option) //选择触发函数事件
         }
        *****/
        simpalSelect: function (options) {
            var target;
            if (typeof options.target === 'string') {
                target = $(options.target);
            } else {
                target = options.target;
            }
            target.children().remove();
            var selectedIt = null;
            if (typeof options.promptMsg !== 'undefined') {
                if (typeof options.promptValue !== 'undefined') {
                    selectedIt = $("<option  value='" + options.promptValue + "'>" + options.promptMsg + "</option>").appendTo(target);
                } else {
                    selectedIt = $("<option  value=''>" + options.promptMsg + "</option>").appendTo(target);
                }
            } else {
                selectedIt = target;
            }
            if ($.isArray(options.data)) {
                $.each(options.data, function (i, o) {
                    var v = o[options.idField];
                    var isSelected = false;
                    if ($.isArray(options.selected)) {
                        $.each(options.selected, function (j, item) {
                            if (v === item) {
                                isSelected = true;
                            }
                        });
                    }
                    var it = null;
                    if (isSelected) {
                        it = $("<option value='" + v + "' selected='selected'>" + o[options.textField] + "</option>").appendTo(target);
                    } else {
                        it = $("<option value='" + v + "' >" + o[options.textField] + "</option>").appendTo(target);
                    }
                    it.data("data", o);
                    if (typeof options.defaultVal === 'string' || typeof options.defaultVal === 'number') {
                        if (options.defaultVal === v) {
                            selectedIt = it;
                        }
                    }
                });
            }
            selectedIt.attr('selected', 'selected');
            if (typeof options.onchange === 'function') {
                target.on('change', function () {
                    var opt = $(this).children("option:selected");
                    options.onchange($(opt));
                });
            }
        },
        /**
         * des加密 依赖于encrypt-min.js
         * ***/
        encryptData: function (message, key) {
            if (typeof window["CryptoJS"] === "undefined") {
                return message;
            }
            if (!key) {
                key = window["SRCUUID"];
            }
            var keyHex = window["CryptoJS"].enc.Utf8.parse(key);
            var encrypted = window["CryptoJS"].DES.encrypt(message, keyHex, {
                mode: window["CryptoJS"].mode.ECB,
                padding: window["CryptoJS"].pad.Pkcs7
            });
            return encrypted.toString();
        },
        _toTreeJson:function(json,treeJson,deep){
            var _this = this;
            setTimeout(function(){
                var keys = Object.keys(json);
                var key,obj,treeObj,prop,props,propObj,i,len,j,jlen,node,id;
                for(i = 0 ,len = keys.length ; i < len ;++i){
                    key = keys[i];
                    obj = json[key];
                    id = '_j'+deep+i;
                    treeObj = {id:id,text:key,data:{}};               
                    if($.isArray(obj)){
                        treeObj.children = [];
                        if(deep > 0){
                            treeObj.closed = true;
                        }
                        for(j = 0 ,jlen = obj.length ; j < jlen ; ++j){
                            node =  {id:id + j,text:key+"["+j+"]",data:{}};
                            treeObj.children.push(node);
                            propObj = obj[j];
                            if($.isPlainObject(propObj)){
                                node.children = [];
                                if(deep > 1){
                                    node.closed = true;
                                }
                                _this._toTreeJson(propObj,node.children,deep++);
                            }else{
                                node.text = node.text + " : "+ propObj;
                            }
                        }
                    }else if($.isPlainObject(obj)){
                        treeObj.children = [];
                        if(deep > 1){
                            treeObj.closed = true;
                        }
                        _this._toTreeJson(obj,treeObj.children,deep++);
                    }else{
                        treeObj.text = key +" : "+obj;
                    }
                    treeJson.push(treeObj);
                }
                _this._createJsonTree();
            },0);           
        },
        /**
         * json-查询器
         * **/
        jsonViewer:function(json,args,onCopy){
            var root = $("<ul class='k_json_view_root'/>");
            var treeJson = [];
            this._toTreeJson(json,treeJson,1);
            this.$jsonTreeUl = root;
            this.treeJson = treeJson;
            var _this = this;
            var winCxt = $("<div style='padding:6px 12px;'></div>");
            winCxt.append("<div><button class='k_icon_fff'><i class='fa fa-docs'></i>"+$B.config.copy+"</button></div>");
            this.copyContent = JSON.stringify(json);
            winCxt.find("button").click(function(e){
                var $txt = _this.$jsonTreeUl.next("textarea");
                if($txt.length > 0){
                    $txt.remove();
                    _this.$jsonTreeUl.show();
                    $(this).html("<i class='fa fa-docs'></i>"+$B.config.copy);
                }else{
                    $(this).html("<i class='fa fa-docs'></i>"+$B.config.recoverCopy);
                    _this.$jsonTreeUl.hide();
                    $("<textarea style='width:100%;height:100%'>"+_this.copyContent+"</textarea>").insertAfter(_this.$jsonTreeUl);
                }               
            });
            winCxt.append(root);
            var winOpts = $.extend({
                width:'70%',
                height:'80%',
                content:winCxt,
                onClose:function(){
                    _this.$jsonTreeUl.data("treeIns").destroy();
                    _this.$jsonTreeUl = undefined;
                    _this.treeJson = undefined;
                    _this.copyContent = undefined;
                }
            },args);
            this.window(winOpts); 
            this.$jsonTreeUl.html("<li>please waiting.....</li>");
        },
        _createJsonTree:function(){
            clearTimeout(this.jsonViewTimer);           
            var _this = this;
            this.jsonViewTimer = setTimeout(function(){
                new $B.Tree(_this.$jsonTreeUl, {
                    plainStyle:true,
                    checkbox: false,
                    data: _this.treeJson
                });               
                _this.treeJson = undefined;
            },300);     
        },
        /**
         * des解密  依赖于encrypt-min.js
         * ***/
        decryptData: function (message, key) {
            if (typeof window["CryptoJS"] === "undefined") {
                return message;
            }
            if (!key) {
                key = window["SRCUUID"];
            }
            var keyHex = window["CryptoJS"].enc.Utf8.parse(key);
            var decrypted = window["CryptoJS"].DES.decrypt({
                ciphertext: window["CryptoJS"].enc.Base64.parse(message)
            }, keyHex, {
                    mode: window["CryptoJS"].mode.ECB,
                    padding: window["CryptoJS"].pad.Pkcs7
                });
            return decrypted.toString(window["CryptoJS"].enc.Utf8);
        },
        getLoadingMask:function(){
            var mask = $("<div  style='position:absolute;z-index: 2147483645;top:0;left:0;width:100%;height:100%;display:block;'><div id='k_window_mask_bg' style='width:100%;height:100%;position:absolute;top:0;left:0;z-index: 2147483646;display:block'></div><div style='text-align:center;width:100%;height:20px;line-height:20px;position:absolute;top:0;left:0;z-index: 2147483647;background: #EEEEEE;'><i class='fa fa-spin5 animate-spin'></i><span style='padding-left:8px;'>正在处理...</span></div></div>");
            return mask;
        },
        _dyFormHclick: function () {
            var $h = $(this);
            var $i = $h.children("i");
            if ($i.hasClass("fa-down-open-big")) {
                $i.removeClass("fa-down-open-big").addClass("fa-right-open-big").css("padding-left","5px");
                $h.next().slideUp(200, function () {
                    $(this).hide();
                });
            } else {
                $i.removeClass("fa-right-open-big").addClass("fa-down-open-big").css("padding-left","0");
                $h.next().show().slideDown(200);
            }
        },
        _dyFormLoad: function (url, el, type,reqId,filedName,dataObj) {
            (function (r, e, t,id,filed,obj,me) {
                $B.request({
                    url: r,
                    ok: function (msg, datas) {
                        delete me.reqQ[id];
                        //obj.data = datas;
                        //console.log(t +" 数据加载完成 "+ JSON.stringify(datas));
                        var $l = e;
                        var $p = e.parent();
                        while($p[0].nodeName !== "TABLE"){
                            $p = $p.parent();
                        }
                        if($p.parent().length === 0){//当前表单已经被销毁
                            return;
                        }
                        var chkVals = [];
                        for(var i = 0 ,len = datas.length ; i < len ;++i){
                            if(datas[i].checked){
                                chkVals.push(datas[i].id);
                            }
                            switch(t){
                                case "select":
                                    if(datas[i].selected){
                                        chkVals.push(datas[i].id);
                                    }
                                    $l.append("<option value='"+datas[i].id+"'>"+datas[i].text+"</option>");
                                break;                          
                                case "radio":
                                    if(datas[i].checked){
                                        chkVals.push(datas[i].id);
                                    }
                                    $l.append('<label class="k_radio_label k_radio_anim"><input type="radio" name="'+filed+'" value="'+datas[i].id+'" /><i class="k_radio_i"></i>'+datas[i].text+'</label>');
                                break;
                                case "checkbox":
                                    if(datas[i].checked){
                                        chkVals.push(datas[i].id);
                                    }
                                    $l.append('<label class="k_checkbox_label k_checkbox_anim"><input type="checkbox" name="'+filed+'" value="'+datas[i].id+'" /><i class="k_checkbox_i"></i>'+datas[i].text+'</label>');
                                break;
                            }
                        }
                        if(chkVals.length > 0){
                            dataObj.defaultVal = chkVals.join(",");
                        }                                        
                    },
                    final:function(){
                        delete me.reqQ[id];
                    }
                });
            })(url, el, type,reqId,filedName,dataObj,this);
        },
        _dyInputWindowClick:function(){
            var $t = $(this);           
            var params = $t.data("params");
            var filedName = params.filedName;
            var url = params.url;
            if(url.indexOf("?") > 0){
                url = url + "&filed="+filedName;
            }else{
                url = url + "?filed="+filedName;
            }
            window["_curDyFiled"] = filedName;           
            window["_curDyWindow"] = $B.window({
                width:'60%',
                height:'70%',
                dataType:'html',
                title:params.title,
                url:url                
            });
        },
        /**
         * 动态表单
         * $wrap:容器
         * formJson：表单定义json
         * formData：表单对应的实体数据对象
         * labelWidth：标签td的宽度
         * **/
        dyForm: function ($wrap, formJson,formData,labelWidth) {           
            clearInterval(this._ivt);
            $wrap.children().remove(); 
            var one, forms, form, $el, $table, $tr, 
                placeholder, data, filedName,attrs,reqId,
                 $tmpEl,m,mlen,opt,defaultValue,ftype;
            var inputWidth;
            if($wrap.width() <= 500){
                inputWidth = "99%";
            }
            var validateObj = {};//验证对象
            var makeObj = false;
            if($.isEmptyObject(formData)){//空的数据对象，则提前表单字段
                makeObj = true;
            }
            var _this = this;
            window["_curDyDataObj"] = formData;
            this.reqQ = {};//用于检测远程请求数据是否完成
            var treeFn = function(muChecked,_data,qId,el,dObj){
                var _opt = {
                     checkbox:muChecked,
                     requestfinal:function(){
                         delete _this.reqQ[qId];
                     }
                 };
                 if(typeof _data === "string"){
                     _opt.url = _data;
                     _this.reqQ[qId] = true;
                 }else{
                     delete _data.unique;
                     _opt.data = _data;                     
                 }
                 new $B.Tree(el, _opt);
             };
             var comboxFn = function(holder,mutilChked,cfather,readonly,_data,qId,$l){
                var _opt = { 
                    placeholder: holder, //默认选择项目                              
                    mutilchecked: mutilChked, //是否多选
                    checkfather: cfather, // 单选的时候，是否可以选择父节点
                    readonly: readonly, //不可以编辑
                    onReqloaded:function(){
                        delete _this.reqQ[qId];
                    }
                };
                if(typeof _data === "string"){
                    _opt.url = _data;                                   
                    _this.reqQ[qId] = true;
                }else{
                    _opt.data = _data;  
                    delete _data.unique;                    
                }
                new $B.Combox($l, _opt);
            };
            for (var i = 0, len = formJson.length; i < len; ++i) {
                one = formJson[i];
                if (one.gName && one.gName !== "") {
                    $el = $(' <h6 style="font-size:14px;padding:4px;font-weight: normal;cursor: pointer;"><i style="padding-right:4px;" class="fa  fa-down-open-big"></i>' + one.gName + '</h6>');
                    $el.appendTo($wrap).click(this._dyFormHclick);
                    if(i > 0){
                        $el.css("border-top","1px solid #CCCCCC");
                    }
                }
                forms = one.forms;
                $table = $('<table style="width:100%;" class="form_table k_dy_form_table"></table>');                                
                for (var j = 0, jlen = forms.length; j < jlen; ++j) {
                    form = forms[j];
                    attrs = form.attrs;
                    ftype = form.ftype;
                    placeholder = form.tip ? form.tip : "";
                    data = form.data ? form.data : "";
                    defaultValue = form.defaultValue;
                    filedName = form.filedName;
                    if(form.valid && form.valid !== ""){
                        validateObj[filedName] = form.valid;
                    }
                    if(makeObj){ // label hidden input window textarea date time select radio checkbox combox tree
                        if(ftype === "label" || ftype === "hidden"  || ftype === "window" || ftype === "input" || ftype === "textarea" || ftype === "date"){
                            formData[filedName] = data;
                        }else if(ftype === "select" || ftype === "radio" || ftype === "checkbox" || ftype === "combox" || ftype === "tree"){
                            if(defaultValue){
                                formData[filedName] = defaultValue;
                            }else{
                                formData[filedName] = "";
                            }
                        }
                    }            
                    $tr = $("<tr/>").appendTo($table);
                    $tr.append('<td style="width:60px;text-align: right;padding:2px 2px;">' + form.title + '</td>').width(labelWidth);
                    switch (form.ftype) {
                        case "label":
                            $tr.append('<td>'+data+'</td>');                             
                            break;
                        case "input":
                            $tr.append('<td><input type="text" id="'+filedName+'" placeholder="'+placeholder+'" value="'+data+'"/></td>');
                            $tmpEl = $tr.find("input");
                            if(attrs){
                                $tmpEl.attr(attrs);
                            }
                            if(inputWidth){
                                $tmpEl.width(inputWidth);
                            }
                            break;
                        case "window": //  
                            $tmpEl = $tr.append('<td><input class="k_window_input" readonly="readonly" type="text" id="'+filedName+'"  placeholder="'+placeholder+'" value="'+data+'"/></td>').find("input");
                            $tmpEl.click(this._dyInputWindowClick).data("params",{
                                filedName:filedName,
                                url:form.url,
                                title:form.title
                            });    
                            if(inputWidth){
                                $tmpEl.width(inputWidth);
                            }                       
                            break;
                        case "select":
                            $tmpEl = $('<td><select id="'+filedName+'"  placeholder="'+placeholder+'"/></td>').appendTo($tr).children("select");
                            if($.isArray(data)){
                                for(m = 0 ,mlen = data.length ; m < mlen ; ++m){
                                    $tmpEl.append("<option value='"+data[m].id+"'>"+data[m].text+"</option>");
                                }
                            }else{//url请求
                                reqId = $B.getUUID();
                                this.reqQ[reqId] = true;
                                this._dyFormLoad(data, $tmpEl, "select",reqId,filedName,form);
                            }     
                            if(attrs){
                                $tmpEl.attr(attrs);
                            }   
                            if(inputWidth){
                                $tmpEl.width(inputWidth);
                            }                    
                            break;
                        case "textarea":
                            $tr.append('<td><textarea  id="'+filedName+'"  placeholder="'+placeholder+'"/>'+data+'</td>');
                            $tmpEl =  $tr.find("textarea");
                            if(attrs){
                                $tmpEl.attr(attrs);
                            }   
                            if(inputWidth){
                                $tmpEl.width(inputWidth);
                            }
                            break;
                        case "radio":
                            $tmpEl = $('<td></td>').appendTo($tr);
                            if(typeof data === "string"){//url请求
                                reqId = $B.getUUID();
                                this.reqQ[reqId] = true;
                                this._dyFormLoad(data, $tmpEl, "radio",reqId,filedName,form);                         
                            }else{
                                delete data.unique;
                                for(m = 0 ,mlen = data.length ; m < mlen ; ++m){
                                    $tmpEl.append('<label class="k_radio_label k_radio_anim"><input type="radio" name="'+filedName+'" value="'+data[m].id+'" /><i class="k_radio_i"></i>'+data[m].text+'</label>');
                                }
                            }
                            break;
                        case "checkbox":
                            $tmpEl = $('<td></td>').appendTo($tr);
                            if(typeof data === "string"){
                                reqId = $B.getUUID();
                                this.reqQ[reqId] = true;
                                this._dyFormLoad(data, $tmpEl, "checkbox",reqId,filedName,form);                            
                            }else{
                                delete data.unique;
                                for(m = 0 ,mlen = data.length ; m < mlen ; ++m){
                                    $tmpEl.append('<label class="k_checkbox_label k_checkbox_anim"><input type="checkbox" name="'+filedName+'" value="'+data[m].id+'" /><i class="k_checkbox_i"></i>'+data[m].text+'</label>');
                                }
                            } 
                            break;
                        case "tree":
                            $tr.children("td").css("vertical-align","baseline"); //vertical-align: baseline;
                            $tmpEl = $tr.append('<td><ul id="'+filedName+'"/></td>').find("ul");                            
                            reqId = $B.getUUID();                            
                            (treeFn)(form.mutilChecked,data,reqId,$tmpEl,form);
                            break;
                        case "combox":
                            $tmpEl = $tr.append('<td><input type="text" id="'+filedName+'"  placeholder="'+placeholder+'"/></td>').find("input");
                            reqId = $B.getUUID();  
                            (comboxFn)(placeholder,form.mutilchecked,form.checkfather,form.readonly,data,reqId,$tmpEl);
                            if(inputWidth){
                                $tmpEl.width(inputWidth);
                            }
                            break;
                        case "date":
                            opt = {
                                fmt:form.fmt,
                                readonly:true
                            };
                            if(data === ""){
                                opt.initValue =  new Date();
                            }
                            $tmpEl = $tr.append('<td><input type="text" id="'+filedName+'"  placeholder="'+placeholder+'" value="'+data+'"/></td>').find("input"); 
                            new $B.Calendar($tmpEl,opt);
                            break;
                        case "time":
                            console.log("待完成....");
                            break;
                    }
                }
                $table.appendTo($wrap);
            }            
            var count = 1;
            var loading;
            if(!$.isEmptyObject(_this.reqQ)){                
                loading = this.getLoadingMask();
                loading.appendTo($wrap);
            }
            if($wrap.data("min")){
                $wrap.children().hide();
            }
            _this._ivt = setInterval(function(){
                if(count > 2000){
                    clearInterval(_this._ivt);
                    $B.error($B.config.requestError);
                    if(loading){
                        loading.remove();
                    }
                }
                console.log("waiting for load the datas ....." + JSON.stringify(_this.reqQ));
                if($.isEmptyObject(_this.reqQ) ){
                    clearInterval(_this._ivt);
                    if(loading){
                        loading.remove();
                    }
                    if(!$.isEmptyObject(validateObj)){
                        new $B.Validate(validateObj,$wrap);
                     }
                     if(formData){//双休绑定实现
                        $B.bindForm($wrap ,formData,function (propObj, propName, newValue, oldValue) {
                           // console.log(" 双休绑定联动 》》》newValue = "+newValue + " ;oldValue="+oldValue);
                        });
                     }
                }
                count++;
            },150);          
        }
    });
    $B.bindTextClear = function ($form) {
        var fn = function () {
            var $text = $(this);
            if (!$text.hasClass("k_combox_input")) {
                $text.on("mouseenter.textbox", TextEvents.mouseover);
                $text.on("input.textbox", TextEvents.input);
                $text.on("mouseleave.textbox", TextEvents.mouseout);
            }
        };
        $form.find("input[type=text]").each(fn);
        $form.find("input[type=password]").each(fn);
    };
    //往所有输入框加上清空按钮    
    $(function () {
        setTimeout(function () {
            $B.bindTextClear($("body"));
        }, 1000);
    });
    window["$B"] = $B;
    return $B;
}));/**
 * 2019-05-23 修复confirm createToolsFn调用bug
 * ****/
(function (global, factory) {
    if (typeof define === 'function' && define.amd  && !window["_all_in_"]) {
        define(['$B', 'plugin', 'panel', 'config'], function (_$B) {
            return factory(global, _$B);
        });
    } else {
        if (!global["$B"]) {
            global["$B"] = {};
        }
        factory(global, global["$B"]);
    }
}(typeof window !== "undefined" ? window : this, function (window, $B) {
    var config = $B.config;
    var document = window.document;
    var $body;

    function _getBody() {
        if (!$body) {
            $body = $(window.document.body).css("position", "relative");
        }
        return $body;
    }
    $.extend($B, {
        /**
         *打开一个窗口
        *arg={
                full:false,//是否满屏，当为true时候，高宽无效
                isTop:false,//是否最顶层打开窗口，默认false
                width:宽度,
                height:高度,
                title:'标题',
                closeType: 'destroy', //关闭类型 hide(隐藏，可重新show)/ destroy 直接从dom中删除
                header:true,//是否显示头部
                draggableHandler:'header',//拖动触发焦点
                iconCls:'',
                position:undefined ,//指定位置 top 、bottom, {top:x ,left : y}
                shadow:true,//是否需要阴影
                draggable:true,//是否可以拖动
                moveProxy:false,//是否代理拖动
                closeable: true,//是否关闭
                maxminable: true,//可变化小大
                collapseable: true,//上下收缩
                content:'内容或者url',
                radius:true,//是否圆角
                closeable: true,//是否可以关闭
                createToolsFn:fn,//自定义创建弹出窗口的按钮
                dataType: 'html',//html/json/iframe
                timeout:0, //自动关闭时间，默认不自动关闭，0表示不自动关闭
                toolbar:工具栏json,优先调用createToolsFn
                mask:true,//是否需要遮罩层
                onClosed:fn, //关闭回调
                onLoaded:fn, //加载完成回调
                onResized:fn //大小发生变化
            }
        返回一个具有close(timeout) api的对象
        ***/
        window: function (args) {
            var _$body, mask = true;
            if (args.isTop) {
                _$body = $(window.top.document.body).css("position", "relative");
            } else {
                _$body = _getBody();
            }
            var _bodyw = _$body.outerWidth(),
                _bodyh = _$body.outerHeight();
            if(typeof args.width === "string"){
                if(args.width.indexOf("%") > 0){
                    args.width = _bodyw * ( parseInt(args.width.replace("%","")) / 100 );
                }else{
                    args.width = parseInt(args.width.replace("px",""));
                }
            }
            if(typeof args.height === "string"){
                if(args.height.indexOf("%") > 0){
                    args.height = _bodyh * ( parseInt(args.height.replace("%","")) / 100 );
                }else{
                    args.height = parseInt(args.height.replace("px",""));
                }
            }
            if (typeof args.mask !== 'undefined') {
                mask = args.mask;
            }
            if (args.full) {
                args.width = _bodyw;
                args.height = _bodyh;
                mask = false;
                args.draggable = false;
                args.collapseable = false;
                args.maxminable = false;
            }
            if (args.width > _bodyw) {
                args.width = _bodyw;
            }
            if (args.height > _bodyh) {
                args.height = _bodyh;
            }
            var _l = (_bodyw - args.width) / 2;
            var _t = (_bodyh - args.height) / 2;
            _t = _t + (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0);
            var $mask = _$body.children("#k_window_mask_bg");
            var uuid = this.generateMixed(6);
            if (mask) {
                if ($mask.length === 0) {
                    $mask = $("<div style='z-index:218000000;position:abosulte;top:-100000px;width:" + _$body[0].scrollWidth + "px;height:" + _$body[0].scrollHeight + "px' for='" + uuid + "' id='k_window_mask_bg'></div>").appendTo(_$body);
                }
                if(args.opacity){
                    $mask.css("opacity",args.opacity);
                }
                if($mask.css("display") === "none"){
                	$mask.css("top", 0).show().attr("for",uuid);
                }
            }
            var $win = $("<div  id='" + uuid + "' style='position:absolute;z-index:2190000000;' class='k_window_main_wrap'></div>");
            var bodyOverflow;
            var posIsPlaintObj ;
            if (args.position) {
                posIsPlaintObj = $.isPlainObject( args.position);
                if(posIsPlaintObj ){
                    $win.css(args.position).appendTo(_$body);
                }else{
                    if (args.position === "bottom") {
                        bodyOverflow = _$body.css("overflow");
                        _$body.css("overflow", "hidden");
                        $win.css({
                            bottom: -1200,
                            right: 0
                        }).appendTo(_$body);
                    } else {
                        $win.css({
                            top: -1200,
                            left: _l
                        }).appendTo(_$body);
                    }
                }
                
            } else {
                $win.css({
                    top: _t,
                    left: _l
                }).appendTo(_$body);
            }
            if (args.full) {
                args.maxminable = false;
            }
            var closeTimer, panel;
            var opts = {
                width: args.width ? args.width : 600,
                height: args.height ? args.height : 300,
                zIndex: 2147483647,
                title: args.title, //标题
                closeType: typeof args.closeType !== 'undefined' ? args.closeType : 'destroy', //关闭类型 hide(隐藏，可重新show)/ destroy 直接从dom中删除
                iconCls: typeof args.iconCls !== 'undefined' ? args.iconCls : 'fa-window-restore', //图标cls，对应icon.css里的class
                shadow: typeof args.shadow !== 'undefined' ? args.shadow : true, //是否需要阴影
                radius: typeof args.radius !== 'undefined' ? args.radius : false, //是否圆角                   
                header: typeof args.header !== 'undefined' ? args.header : true, //是否显示头部
                content: args.content, // args.content,
                url: args.url ? args.url:"",
                position: args.position,
                dataType: typeof args.dataType !== 'undefined' ? args.dataType : 'iframe', //当为url请求时，html/json/iframe
                draggableHandler: args.draggableHandler, //拖动触发焦点
                moveProxy: typeof args.moveProxy !== 'undefined' ? args.moveProxy : false, //是否代理拖动
                draggable: typeof args.draggable !== 'undefined' ? args.draggable : true, //是否可以拖动
                closeable: typeof args.closeable !== 'undefined' ? args.closeable : true, //是否关闭
                expandable: false, //可左右收缩                
                maxminable: typeof args.maxminable !== 'undefined' ? args.maxminable : true, //可变化小大
                collapseable: typeof args.collapseable !== 'undefined' ? args.collapseable : true, //上下收缩
                onResized: typeof args.onResized === 'function' ? args.onResized : undefined, //大小变化事件
                onLoaded: typeof args.onLoaded === 'function' ? args.onLoaded : undefined, //加载完成
                onStartDrag: typeof args.onStartDrag === 'function' ? args.onStartDrag : undefined, //开始拖动事件
                onDrag: typeof args.onDrag === 'function' ? args.onDrag : undefined, //拖动中事件
                onStopDrag: typeof args.onStopDrag === 'function' ? args.onStopDrag : undefined, //拖动结束事件
                toolbar: args.toolbar  ? args.toolbar : undefined, //加载完成
                onClose: function () { //关闭前
                    //console.log("关闭前 >>>>> ");
                    var goClose = true;
                    if (typeof args.onClose === 'function') {
                        goClose = args.onClose();
                    }
                    if (goClose) {
                        clearTimeout(closeTimer);
                    }
                    return goClose;
                },
                onClosed: function () { //关闭后
                    //这里应该判断关闭的窗口 是否关联到 $mask
                    var forId =  $mask.attr("for");
                    var winId = this.attr("id");                   
                    if(forId === winId){
                        $mask.hide();   
                    }             
                    if (typeof args.onClosed === 'function') {
                        args.onClosed();
                    }
                }
            };
            if (args.createToolsFn) {
                opts["createToolsFn"] = args.createToolsFn;
            }
            opts = $.extend({}, config.winDefOpts, opts);
            if(args.timeout && args.timeout < 5){
                opts.closeable = false;
            }
            panel = new $B.Panel($win, opts);
            if(panel.$header){
                panel.$header.addClass("k_window_header_wrap");
            }            
            if (args.timeout) {
                closeTimer = setTimeout(function () {
                    if (opts.closeType === "destroy") {
                        panel.destroy();
                    } else {
                        panel.close(true);
                    }
                }, args.timeout * 1000);
            }
            if (args.position && !posIsPlaintObj) {
                if (args.position === "bottom") {
                    $win.show();
                    $win.show().animate({
                        bottom: 0
                    }, 300, function () {
                        _$body.css("overflow", bodyOverflow);
                    });
                } else {
                    $win.show().animate({
                        top: 1
                    }, 300);
                }
            }
            return panel;
        },
        /**
         *信息提示框
        *args={
                title:'请您确认',
                iconCls:'图标样式',
                message:'提示信息！', //提示信息或者创建html内容的函数
                contentIcon:'内容区域的图标',
                iconColor:'',//内容区域图标颜色
                width: ,//宽度
                height:,//高度         
                timeout:自动消失时间,
                mask://是否需要遮罩,
                toolbar:[],//工具栏的按钮
                createToolsFn://创建工具按钮的函数，优先调用创建函数
        }
        ***/
        message: function (args) {
            var $icon,
                $content,
                position,
                titleIcon = 'fa-mail-alt';
            if (typeof args.message === "function") { //调用创建函数
                $content = args.message();
                if (typeof $content !== "string") {
                    $icon = $content.children(".k_window_content_icon");
                }
            } else if (typeof args === 'string') {
                args  = {message:args};
                if(arguments.length === 2){
                    args.timeout = arguments[1];
                 }
            } 
            $content = $('<div class="k_window_content_wrap clearfix"><div class="k_window_content_icon"></div><p class="k_box_size k_window_content_p">' + args.message + '</p></div>');
            var icon = args.contentIcon ? args.contentIcon : "fa-chat-empty";
            var $i = $("<i class='fa " + icon + "'>\u200B</i>").appendTo($content.children(".k_window_content_icon"));
            if (args.iconColor) {
                $i.css("color", args.iconColor);
            }
            delete args.iconColor;
            $icon = $content.children(".k_window_content_icon");
            position = args.position;
            if (args.iconCls) {
                titleIcon = args.iconCls;
            }
            var opts = {
                width: 400,
                height: 200,
                position: position,
                title: config.messageTitle, //标题
                iconCls: titleIcon, //图标cls，对应icon.css里的class
                shadow: true, //是否需要阴影
                timeout:  args.timeout ?  args.timeout : 0, //5秒钟后自动关闭
                mask: true, //是否需要遮罩层
                draggableHandler: 'header',
                radius: false, //是否圆角
                header: true, //是否显示头部
                content: $content,
                draggable: true, //是否可以拖动
                closeable: true, //是否关闭
                expandable: false, //可左右收缩
                maxminable: false, //可变化小大
                collapseable: false //上下收缩
            };
            $.extend(opts, args);
            var _opts = $.extend(opts, args);
            var $p = $content.children("p");
            if ($icon) {
                _opts["onResized"] = function () {
                    var h = $p.height() + "px";
                    $icon.children("i").css({
                        "line-height": h,
                        "height": h,
                        "display": "block"
                    });
                };
            }
            var win = this.window(_opts);
            var h = $content.height();
            var iconWidth = $icon ? $icon.outerWidth() : 0;
            var width = $p.outerWidth() + iconWidth;
            var contentWidth = $content.width();
            //实现居中
            var diff = contentWidth - width;
            if (diff > 0) {
                if ($icon && $icon.length > 0) {
                    $icon.css("margin-left", diff / 2);
                } else {
                    $p.css("margin-left", diff / 2);
                }
            }
            var _h;
            var infh = $p.outerHeight();
            if (infh > h) {
                _h = infh - h + 20 + _opts.height;
                // var max_width = contentWidth - iconWidth - 2;
                // $p.css("max-width", max_width + 'px');
                win.resize({
                    height: _h
                });
            } else {
                var paddingtop = parseInt($p.css("padding-top").replace("px"));
                $p.css("margin-top", (h - infh) / 2 - paddingtop / 2);
                if ($icon) {
                    $icon.children("i").css({
                        "line-height": h + "px",
                        "height": h,
                        "display": "block"
                    });
                }
            }
            return win;
        },
        /**
         *成功信息
        *arg={
                message:'提示内容',
                width:,
                height:,
                iconCls:'图标样式',
                timeout:自动消失时间,
                title:'标题',
                mask://是否需要遮罩
        }
        ***/
        success: function (args) {
            var opts = {
                width: 400,
                height: 180,
                title: config.successTitle, //标题
                iconCls: ' fa-check', //
                shadow: true, //是否需要阴影
                timeout: 0, //5秒钟后自动关闭
                mask: true, //是否需要遮罩层
                contentIcon: 'fa-ok-circled',
                iconColor: '#3BB208',
                draggableHandler: 'header'
            };
            if (typeof args === "string") {
                opts.message = args;
                if(arguments.length === 2){
                   opts.timeout = arguments[1];
                }
            } else {
                $.extend(opts, args);
            }
            var win = this.message(opts);
            return win;
        },
        /**
         *警告信息
        *arg={
                message:'提示内容',
                width:,
                height:,
                iconCls:'图标样式',
                timeout:自动消失时间,
                title:'标题',
                mask://是否需要遮罩
        }
        ***/
        alert: function (args) {
            var opts = {
                width: 400,
                height: 150,
                title: config.warnTitle, //标题
                iconCls: 'fa-attention-circled', //图标cls，对应icon.css里的class
                shadow: true, //是否需要阴影
                timeout: 0, //5秒钟后自动关闭
                mask: true, //是否需要遮罩层
                contentIcon: 'fa-attention-1',
                iconColor: '#BFBC03',
                draggableHandler: 'header'
            };
            if (typeof args === "string") {
                opts.message = args;
                if(arguments.length === 2){
                    opts.timeout = arguments[1];
                 }
            } else {
                $.extend(opts, args);
            }
            var win = this.message(opts);
            return win;
        },
        /**
         * message 错误信息对话框
         * opts = {
                width: 400,
                height: 150,
                title: config.errorTitle, //标题
                iconCls: 'fa-cancel-2', //图标cls，对应icon.css里的class
                shadow: true, //是否需要阴影
                timeout: 0, //5秒钟后自动关闭
                mask: true, //是否需要遮罩层
                contentIcon: 'fa-cancel-circled',
                iconColor: '#F7171C',
                draggableHandler: 'header'
        }
        * ***/
        error: function (args) {
            var opts = {
                width: 400,
                height: 150,
                title: config.errorTitle, //标题
                iconCls: 'fa-attention-1', //图标cls，对应icon.css里的class
                shadow: true, //是否需要阴影
                timeout: 0, //5秒钟后自动关闭
                mask: true, //是否需要遮罩层
                contentIcon: 'fa-cancel-circled',
                iconColor: '#F7171C',
                draggableHandler: 'header'
            };
            if (typeof args === "string") {
                opts.message = args;
                if(arguments.length === 2){
                    opts.timeout = arguments[1];
                 }
            } else {
                $.extend(opts, args);
            }
            var win = this.message(opts);
            return win;
        },
        /**
         * 确认提示框
         * args={
                title:'请您确认',
                iconCls:'图标样式',
                message:'提示信息！',
                toolbar:[],//工具栏，如果传入，则不生成默认的按钮
                contentIcon:'内容区域的图标',
                width: ,//宽度
                height:,//高度
                okIcon = "fa-ok-circled",
                okText = "确认",
                noIcon = "fa-ok-circled",
                noText = "取消",
                okFn:fn, //确认回调
                noFn:fn, //否定回调
                contentFn:,//创建内容的函数，返回jq标签
                createToolsFn://创建工具按钮的函数，当不存在toolbar的时候生效，有默认的createToolsFn，this为工具类的jq对象容器
        }
        * ***/
        confirm: function (args) {
            var opts = {
                width: 400,
                height: 150,
                title: config.confirmTitle, //标题
                iconCls: 'fa-question', //图标cls，对应icon.css里的class
                shadow: true, //是否需要阴影
                timeout: 0, //5秒钟后自动关闭
                mask: true, //是否需要遮罩层
                contentIcon: 'fa-help-1',
                draggableHandler: ''
            };           
            var okFn = args.okFn,
                noFn = args.noFn,
                win,
                buttonColor = "#F8F8F8";
            if (args.buttonColor) {
                buttonColor = args.buttonColor;
            }
            delete args.okFn;
            delete args.noFn;
            delete args.buttonColor;
            var okIcon = args.okIcon ? args.okIcon : "fa-ok-circled",
                okText = args.okText ? args.okText : config.buttonOkText,
                noIcon = args.noIcon ? args.noIcon : "fa-reply-all",
                noText = args.noText ? args.noText : config.buttonCancleText;

            delete args.okIcon;
            delete args.okText;
            delete args.noIcon;
            delete args.noText;

            if (typeof args === "string") {
                opts.message = args;
                if(arguments.length === 2){
                    opts.timeout = arguments[1];
                 }
            } else {
                $.extend(opts, args);
            }
            if (typeof args.createToolsFn === "function") {
                opts["createToolsFn"] = args.createToolsFn;
            } else {
                opts["createToolsFn"] = function () {
                    var wrap = this;
                    var tool = $("<div class='k_confirm_buttons_wrap'></div>").appendTo(wrap);
                    var ybtn = $("<button class='yes'><i  class='fa " + okIcon + "'>\u200B</i>" + okText + "</button>").appendTo(tool).click(function () {
                        var goClose = true;
                        if (typeof okFn === "function") {
                            var res = okFn();
                            if (typeof res !== "undefined") {
                                goClose = res;
                            }
                        }
                        if (goClose) {
                            win.close(true);
                        }
                    });
                    var nbtn = $("<button class='no'><i  class='fa " + noIcon + "'>\u200B</i>" + noText + "</button>").appendTo(tool).click(function () {
                        var goClose = true;
                        if (typeof noFn === "function") {
                            var res = noFn();
                            if (typeof res !== "undefined") {
                                goClose = res;
                            }
                        }
                        if (goClose) {
                            win.close(true);
                        }
                    });
                    // setTimeout(function () {
                    //     tool.parent().css("padding-bottom", 0);
                    // }, 10);
                    return tool;
                };
            }
            win = this.message(opts);
            return win;
        }
    });
    /************CURD基本常用API封装*****
    配合datagrid实现的通用表格增删改查
    通用的CURD对象，用于结合datagrid实现表单通用的curd操作api封装**/
    function CURD(tableObj, opts) {
        var gdOpts = $.extend({}, $B.config.curdDatagridOpts, opts);
        this.opts = $B.config.curdOpts;
        this.id = gdOpts.id;
        this.curWindow = null; //当前打开的window
        this.idField = gdOpts.idField;
        var httpHost = $B.getHttpHost();
        if(gdOpts.url.indexOf(httpHost) >= 0){
            this.url = gdOpts.url;
        }else{
            this.url = httpHost + gdOpts.url;
        }        
        var _url = this.url;
        if (this.url && !/gridid=\w+/.test(this.url)) {
            if (this.url.indexOf("?") > 0) {
                _url = this.url + "&gridid=" + this.id;
            } else {
                _url = this.url + "?gridid=" + this.id;
            }
        }
        gdOpts.url = _url;
        this.dg = new $B.Datagrid(tableObj, gdOpts);
    }
    CURD.prototype = {
        constructor: CURD,
        /**获取datagrid对象**/
        getDataGrid: function () {
            return this.dg;
        },
        /** 打开行内嵌页面
         args= {
                target:'行jQuery对象',
                content:'内容或者url'
                type:'如果是url请求的时候，type=html/iframe',
                onLoaded:function() {如果是url加载，会触发加载完成事件}
          }****/
        openInner: function (args) {
            this.dg.openInner(args);
        },
        /**打开一个操作窗口 一般用于弹出新增、修改窗口
         * args={
                width:500,
                height:200,
                title: '我是测试表头',//标题
                iconCls: 'icon-user',//图标cls，对应icon.css里的class
                shadow:true,//是否需要阴影
                timeout:0,//5秒钟后自动关闭
                mask:true,//是否需要遮罩层
                radius:false,//是否圆角
                header:true,//是否显示头部
                content:'<div><p></p></div>',
                draggableHandler:'header',//拖动触发焦点
                draggable:true,//是否可以拖动
                moveProxy:true,//代理拖动
                closeable: true,//是否关闭
                expandable: false,//可左右收缩
                maxminable:true,//可变化小大
                collapseable: true,//上下收缩
                onResized:function(){//大小变化事件
                    console.log(" onResized  onResized  onResized");
                },
                onClose:function(){ //关闭前
                    console.log("可以关闭了..................");
                    return true;
                },
                onClosed: function () {//关闭后
                    console.log("window关闭了..................");
                }
        }
        isUpdated 是否是打开修改窗口
        ***/
        window: function (args, isUpdated) {
            if($.isPlainObject(args.params)){
                var tmp = [];
                var keys = Object.keys(args.params);
                for(var i = 0 ,len = keys.length ; i < len ;++i){
                    tmp.push(keys[i]+"="+args.params[keys[i]]);
                }
                args.params = tmp.join("&");
            }
            if (isUpdated) {
                var id;
                if (args.rowData) {
                    id = args.rowData[this.idField];
                } else {
                    var chkdatas = this.dg.getCheckedId();
                    if (chkdatas.length === 0) {
                        var msg = typeof args.message === 'undefined' ? $B.config.need2CheckedData : args.message;
                        $B.alert(msg);
                        return;
                    }
                    if (chkdatas.length > 1) {
                        $B.alert($B.config.onlyGetOneData);
                        return;
                    }
                    id = chkdatas[0];
                }
                if (args.params !== undefined && args.params !== '') {
                    args.params = args.params + '&id=' + id;
                } else {
                    args.params = 'id=' + id;
                }
                if (!args["iconCls"]) {
                    args["iconCls"] = "fa-edit";
                }
            }
            var opts = $.extend({}, $B.config.curdWinDefOpts, args);
            var pageName = (opts.pageName && opts.pageName !== "") ? opts.pageName : "form";
            opts.url = this.url.replace(/\?\S+/, '').replace(/list/, $B.config.curdOpts.page_action) + "/" + pageName;
            if (opts.params && opts.params !== '') {
                opts.url = opts.url + "?" + opts.params;
            }
            delete opts.pageName;
            delete opts.params;
            this.curWindow = $B.window(opts);
            return this.curWindow;
        },
        /**
         * 用于$B.window()与curd.window()共用页面时候
         * 便于内部curdObj.add/update能够自动关闭窗口
         * **/
        setOpenWindow: function (win) {
            this.curWindow = win;
        },
        /*** 关闭当前打开的窗口***/
        close: function () {
            if (this.curWindow !== null && this.curWindow.close) {
                this.curWindow.close();                
            }
            this.curWindow = null;
        },
        closeWindow: function () {
            this.close();
        },
        /**新增args=
         {
            data:{}, //提交的参数
            ok:function(data,message){}//成功处理后的回调,
            final:function(res){} //无论成功，失败都回调的事件
        }/
        args = {f1:xx,f2:xx...};
        ***/
        add: function (args) {
            var url = this.url.replace(/\?\S+/, '').replace(/list/, $B.config.curdOpts.add_action);
            this._save(args, url);
        },
        /**
         * 更新 args={
            data:{},
            ok:function(data,message){},
            final:function(res){}
        }/
        args = {f1:xx,f2:xx...};
        * **/
        update: function (args) {
            var url = this.url.replace(/\?\S+/, '').replace(/list/, $B.config.curdOpts.update_action);
            this._save(args, url);
        },
        /**add / update 的内部调用函数**/
        _save: function (args, url) {
            var _this = this;
            var opts;
            if (args.data && (typeof args.url !== "undefined" || typeof args.fail === "function" || typeof args.ok === "function" || typeof args.ok === "final")) {
                opts = args;
            } else {
                opts = {
                    data: args,
                    ok: function (message, data) {
                        _this.close();
                        _this.reload({
                            page: 1
                        });
                    }
                };
            }
            opts.url = url;
            $B.request(opts);
        },
        /**删除数据 idArray = 需要删除的id数组 ***/
        deleteData: function (idArray) {
            this._del({},idArray);
        },
        /**删除复选的数据 args={
            message:'提示信息',
            params:{},
            ok:function(data,message){},
            final:function(res){},
            fail:function(){}
            }
            * **/
        delChecked: function (args) {
            var chkdatas = this.dg.getCheckedId();
            this._del(args,chkdatas);
        },
        _del:function(args,idArray){
            if (idArray.length === 0) {
                var msg = ( !args || typeof args.message === 'undefined' )? $B.config.need2CheckForDel : args.message;
                $B.alert(msg);
                return;
            }
            var _this = this;
            $B.confirm({
                message: $B.config.confirmDelete,
                okFn:function(){
                    var deleteAll = _this.dg.getRowCount() === idArray.length;
                    var url = _this.url.replace(/\?\S+/, '').replace(/list/, $B.config.curdOpts.del_action);
                    var opts = {
                        url: url,
                        data: { idList: idArray.join(",") },
                        ok: function (message, data) {
                            _this.close();
                            if(deleteAll){
                                _this.reload({
                                    page: 1
                                });                                
                            }else{
                                _this.refresh();
                            }
                        }
                    };
                    $B.request(opts);
                }
            });
        },
        /**
         * 获取复选的数据
         * ***/
        getCheckedData: function () {
            return this.dg.getCheckedData();
        },
        /**
         * 获取复选的数据id
         * ***/
        getCheckedId: function () {
            return this.dg.getCheckedId();
        },
        /**获取所有数据**/
        getData: function () {
            return this.dg.getCheckedData(true);
        },
        /**根据参数查询多条数据
         args={
            params:{},
            ok:function(data,message){}
        }
        ****/
        query: function (args) {
        },
        /**根据id查询单条数据
        args={
            id:id
            ok:function(data,message){}
            }
            ***/
        get: function (args) { },
        /**
         * 重新加载
         * args={} 查询参数
         * ****/
        reload: function (args) {
            this.dg.reload(args);
        },
        /**
         * 采用上一次查询的参数刷新当前页
         * **/
        refresh: function () {
            this.dg.refresh();
        }
    };
    $B["CURD"] = CURD;
    /**
     * 获取一个curd实例
     * 请参考curd参数
     * ***/
    $B["getCURD"] = function (tableObj, args) {
        return new CURD(tableObj, args);
    };
    return $B;
}));(function (global, factory) {
    if (typeof define === 'function' && define.amd) {
        define(['$B'], function (_$B) {
            return factory(global, _$B);
        });
    } else {
        if(!global["$B"]){
            global["$B"] = {};
        }
        factory(global, global["$B"]);
    }
}(typeof window !== "undefined" ? window : this, function (window, $B) {
    function _createItme(item) {
        var it = {
            header: $("<h6 class='k_accordion_header k_box_size'>" + item.name + "</h6>").appendTo(this.jqObj),
            body: $("<div class='k_accordion_body k_box_size'></div>").appendTo(this.jqObj).hide()
        };
        it.header.data("title", item.name);
        if (item.url && item.url !== "") {
            it.body.data("url", item.url).data("type", item.type ? item.type : 'iframe');
        }else if(item.content){
            it.body.append(item.content);
        }
        if (typeof this.opts.onCreate === "function") {
            this.opts.onCreate.call(it.body, item.name);
        }
        if (item.icon && item.icon !== "") {
            it.header.prepend("<i style='padding-right:4px' class='fa " + item.icon + "'></i>");
        }
        return it;
    }

    function _click(e) {
        var $t = $(this);
        var index = $t.data("index");
        var _this = $t.data("_this");
        if (index === _this.actived.index) {
            return;
        }
        var adjust = 0,
            toHide = _this.actived.body,
            toShow = _this.items[index].body,
            duration,
            easing,
            boxSizing = toShow.css("box-sizing"),
            total = toShow.show().outerHeight();
        _this.actived.header.removeClass("k_accordion_header_actived").children(".k_accordion_header_icon").children("i").removeClass(_this.opts.iconClsAct).addClass(_this.opts.iconCls);
        _this._retoreStyle(_this.actived.header);
        _this.items[index].header.addClass("k_accordion_header_actived").children(".k_accordion_header_icon").children("i").removeClass(_this.opts.iconCls).addClass(_this.opts.iconClsAct);
        _this.actived = _this.items[index];
        _this._setActivedStyle();
        toHide.animate(_this.hideProps, {
            duration: duration,
            easing: easing,
            step: function (now, fx) {
                fx.now = Math.round(now);
            }
        });
        toShow.hide().animate(_this.showProps, {
            duration: duration,
            easing: easing,
            complete: function () {
                _this._onOpened();
            },
            step: function (now, fx) {
                fx.now = Math.round(now);
                if (fx.attr !== "height") {
                    if (boxSizing === "content-box") {
                        adjust += fx.now;
                    }
                } else if (_this.opts.heightStyle !== "content") {
                    fx.now = Math.round(total - toHide.outerHeight() - adjust);
                    adjust = 0;
                }
            }
        });
    }

    function Accordion(jqObj, opts) {
        $B.extend(this, Accordion); //继承父类        
        this.jqObj = jqObj.addClass("k_box_size k_accordion_main_wrap");
        this.opts = $.extend(true, {
            heightStyle: 'auto',
            iconCls: 'fa-angle-double-right', //收起图标
            iconClsAct: 'fa-angle-double-down', //展开图标
            iconPositon: 'right', //图标位置
            iconColor: '#666666', //图标颜色
            fontStyle: {
                "font-size": "14px",
                "font-weight": "bold",
                "color": "#666666"
            }, //标题字体颜色、大小配置
            activedStyle: {
                "background": "#71B9EA",
                "color": "#FFFFFF",
                "iconColor": '#FFFFFF'
            }, //激活状态样式            
            accordionStyle: {
                "background": "#F6F6F6",
                "border": "1px solid #C5C5C5"
            }, //手风琴边框、颜色定义
        }, opts);
        if (typeof this.opts.width !== 'undefined') {
            this.jqObj.outerWidth(this.opts.width);
        }
        if (typeof this.opts.height !== 'undefined') {
            this.jqObj.outerHeight(this.opts.height);
        } else {
            this.jqObj.outerHeight(this.jqObj.parent().height());
        }
        this.hideProps = {
            "borderTopWidth": "hide",
            "borderBottomWidth": "hide",
            "paddingTop": "hide",
            "paddingBottom": "hide",
            "height": "hide"
        };
        this.showProps = {
            "borderTopWidth": "show",
            "borderBottomWidth": "show",
            "paddingTop": "show",
            "paddingBottom": "show",
            "height": "show"
        };
        this.items = {};
        var _this = this;
        this.actived = undefined;
        this.bodyHeight = 0;
        var wrapHeight = this.jqObj.height();
        var ml = "14";
        if (this.opts.iconPositon === "left") {
            ml = "0";
        }
        for (var i = 0, len = this.opts.items.length; i < len; ++i) {
            var item = this.opts.items[i];
            var it = _createItme.call(this, item);
            it.header.css(this.opts.fontStyle).css(this.opts.accordionStyle);
            it.body.css("border", this.opts.accordionStyle.border).css("border-top", "none").attr("_title", it.name);
            it["index"] = i;
            var headerH = it.header.outerHeight();
            wrapHeight = wrapHeight - headerH - parseInt(it.header.css("margin-top").replace("px", ""));
            this.items[i] = it;
            it.header.click(_click).data("index", i).data("_this", _this);
            if (this.opts.iconCls && this.opts.iconCls !== "") {
                var icon = $("<div style='margin-left:" + ml + "px;margin-right:12px;float:" + this.opts.iconPositon + ";' class='k_accordion_header_icon'><i class='fa " + this.opts.iconCls + "'></i></div>");
                if ((typeof item.actived === "boolean" && item.actived) || i === 0) {
                    this.actived = it;
                }
                icon.appendTo(it.header).css("color", this.opts.iconColor);
                var iconH = icon.height();
                var marginTop = (headerH - iconH) / 2;
                icon.css("margin-top", marginTop);
            }

        }
        this.bodyHeight = wrapHeight;
        this.actived.header.addClass("k_accordion_header_actived");
        this.actived.body.outerHeight(this.bodyHeight).show();
        this.actived.header.children(".k_accordion_header_icon").children("i").removeClass(this.opts.iconCls).addClass(this.opts.iconClsAct);
        Object.keys(this.items).forEach(function (key) {
            _this.items[key].body.outerHeight(_this.bodyHeight);
        });
        this._setActivedStyle();
        this._onOpened();
    }
    Accordion.prototype = {
        _onOpened: function () {
            if (typeof this.opts.onOpened === "function") {
                this.opts.onOpened.call(this.actived.body, this.actived.header.data("title"));
            }
            var opts = this.opts;
            var url = this.actived.body.data("url");
            if(!url){
                return ;
            }
            if(url.indexOf("?") > 0){
                url = url + "&_t_="+$B.generateMixed(5);
            }else{
                url = url + "?_t_="+$B.generateMixed(5);
            }
            if (url && this.actived.body.children().length === 0) {
                var type = this.actived.body.data("type");
                var $content = this.actived.body;
                var loading = $("<div style='padding-left:16px;'><i class='fa fa-cog fa-spin fa-1.6x fa-fw margin-bottom'></i>" + $B.config.loading + "</div>").appendTo($content);
                if (type === 'html') {
                    $B.htmlLoad({
                        target: $content,
                        url: url,
                        loaded: function () {
                            loading.remove();
                            if (typeof opts.onLoaded === 'function') {
                                opts.onLoaded.call($content, type);
                            }
                            $B.bindTextClear($content);
                        }
                    });
                } else if (type === 'iframe') {
                    var iframe = $("<iframe  frameborder='0' style='overflow:visible' scrolling='auto' width='100%' height='100%' src='' ></iframe>").appendTo($content.css('overflow', 'hidden'));
                    var ifr = iframe[0];
                    iframe.on("load",function(){
                        loading.remove();
                        if (typeof opts.onLoaded === 'function') {
                            opts.onLoaded.call($content);
                        }
                    });
                    ifr.src = url;
                } else { //json加载
                    var ajaxOpts = {
                        async: true,
                        url: url,
                        ok: function (message, data) {
                            if (typeof opts.onLoaded === 'function') {
                                opts.onLoaded.call($content, type, data);
                            }
                        },
                        final: function (res) {
                            loading.remove();
                        }
                    };
                    this.ajax(ajaxOpts);
                }
            }
        },
        _retoreStyle: function ($it) {
            $it.css(this.opts.fontStyle).css("background", this.opts.accordionStyle.background).children("i").css("color", this.opts.iconColor);
            $it.children().children("i").css("color", this.opts.iconColor);
        },
        _setActivedStyle: function () {
            this.actived.header.css(this.opts.activedStyle).children("i").css("color", this.opts.activedStyle.iconColor);
            this.actived.header.children().children("i").css("color", this.opts.activedStyle.iconColor);
            this.actived.body.css(this.opts.accordionStyle);
        }
    };
    $B["Accordion"] = Accordion;
    return $B["Accordion"];
}));(function (global, factory) {
    if (typeof define === 'function' && define.amd  && !window["_all_in_"]) {
        define(['$B', 'panel'], function (_$B) {
            return factory(global, _$B);
        });
    } else {
        if (!global["$B"]) {
            global["$B"] = {};
        }
        factory(global, global["$B"]);
    }
}(typeof window !== "undefined" ? window : this, function (window, $B) {
    var $doc = $(window.document);
    var defaults = {
        animationSpeed: 10,
        animationEasing: 'swing',
        change: null,
        control: 'hue',
        defaultValue: '',
        letterCase: 'lowercase',
        opacity: true,
        update2Target: true,
        showCaret: false,
        position: 'bottom left',
        positionFix: undefined,
        onfocus: null,
        onStartFn: null,
        onEndFn: null,
        onHideFn: null,
        theme: 'default',
        buttons: ['transparent', "#ffffff",
        "#000000", "#aaaaaa", "#CCCCCC", "#dddddd", 
        "#FF0505", "#DE0D4F", "#FC05A1", "#F558E8", 
        "#1803FF", "#633AE0", "#A8A8FA", "#BECEFA", 
        "#03DE24", "#00EBE3", "#8EDB98", "#DBE803", 
        "#D8E062", "#E8EAAD", "#FAF0E6", "#A020F0",
        "#990033", "#FFC0CB", "#428BCA","#5CB85C" ,
        "#5BC0DE" ,"#8B6D38","#0376F0" ,"#878F97" , 
        "#6C757D","#F7F4F8","#F3DEDE","#303133","#E4E7ED","#E1F3D8"
        ] 
    };

    function keepWithin(value, min, max) {
        if (value < min) {
            value = min;
        }
        if (value > max) {
            value = max;
        }
        return value;
    }
    function hsb2rgb(hsb) {
        var rgb = {};
        var h = Math.round(hsb.h);
        var s = Math.round(hsb.s * 255 / 100);
        var v = Math.round(hsb.b * 255 / 100);
        if (s === 0) {
            rgb.r = rgb.g = rgb.b = v;
        } else {
            var t1 = v;
            var t2 = (255 - s) * v / 255;
            var t3 = (t1 - t2) * (h % 60) / 60;
            if (h === 360) {
                h = 0;
            }
            if (h < 60) {
                rgb.r = t1;
                rgb.b = t2;
                rgb.g = t2 + t3;
            } else if (h < 120) {
                rgb.g = t1;
                rgb.b = t2;
                rgb.r = t1 - t3;
            } else if (h < 180) {
                rgb.g = t1;
                rgb.r = t2;
                rgb.b = t2 + t3;
            } else if (h < 240) {
                rgb.b = t1;
                rgb.r = t2;
                rgb.g = t1 - t3;
            } else if (h < 300) {
                rgb.b = t1;
                rgb.g = t2;
                rgb.r = t2 + t3;
            } else if (h < 360) {
                rgb.r = t1;
                rgb.g = t2;
                rgb.b = t1 - t3;
            } else {
                rgb.r = 0;
                rgb.g = 0;
                rgb.b = 0;
            }
        }
        return {
            r: Math.round(rgb.r),
            g: Math.round(rgb.g),
            b: Math.round(rgb.b)
        };
    }
    function rgb2hex(rgb) {
        var hex = [
            rgb.r.toString(16),
            rgb.g.toString(16),
            rgb.b.toString(16)
        ];
        $.each(hex, function (nr, val) {
            if (val.length === 1) {
                hex[nr] = '0' + val;
            }
        });
        return '#' + hex.join('');
    }

    function hsb2hex(hsb) {
        return rgb2hex(hsb2rgb(hsb));
    }

    function hex2hsb(hex) {
        var hsb = rgb2hsb(hex2rgb(hex));
        if (hsb.s === 0) {
            hsb.h = 360;
        }
        return hsb;
    }

    function rgb2hsb(arg) {
        var rgb = arg;
        var hsb = {
            h: 0,
            s: 0,
            b: 0
        };
        var min = Math.min(rgb.r, rgb.g, rgb.b);
        var max = Math.max(rgb.r, rgb.g, rgb.b);
        var delta = max - min;
        hsb.b = max;
        hsb.s = max !== 0 ? 255 * delta / max : 0;
        if (hsb.s !== 0) {
            if (rgb.r === max) {
                hsb.h = (rgb.g - rgb.b) / delta;
            } else if (rgb.g === max) {
                hsb.h = 2 + (rgb.b - rgb.r) / delta;
            } else {
                hsb.h = 4 + (rgb.r - rgb.g) / delta;
            }
        } else {
            hsb.h = -1;
        }
        hsb.h *= 60;
        if (hsb.h < 0) {
            hsb.h += 360;
        }
        hsb.s *= 100 / 255;
        hsb.b *= 100 / 255;
        return hsb;
    }

    function hex2rgb(hex) {
        hex = parseInt(((hex.indexOf('#') > -1) ? hex.substring(1) : hex), 16);
        return {
            r: hex >> 16,
            g: (hex & 0x00FF00) >> 8,
            b: (hex & 0x0000FF)
        };
    }

    function parseHex(string, expand) {
        string = string.replace(/[^A-F0-9]/ig, '');
        if (string === undefined || string === "") {
            return "";
        }
        var len = string.length;
        var diff = 6 - len,
            lastChar;
        if (diff) {
            lastChar = string[len - 1];
        }
        while (diff > 0) {
            string += lastChar;
            diff--;
        }
        return '#' + string;
    }

    function convertCase(string, letterCase) {
        return letterCase === 'uppercase' ? string.toUpperCase() : string.toLowerCase();
    }

    function getCoords(picker, container) {
        var left, top;
        if (!picker.length || !container) {
            return null;
        }
        left = picker.offset().left;
        top = picker.offset().top;
        return {
            x: left - container.offset().left + (picker.outerWidth() / 2),
            y: top - container.offset().top + (picker.outerHeight() / 2)
        };
    }
    /***
     * css =  {hex:,opacity:}
     * **/
    function updateFromInput(css) {
        var hex = css["hex"],
            hsb,
            opacity = css["opacity"],
            x, y, r, phi,
            minicolors = this.jqObj,
            settings = this.opts,
            swatch = minicolors.find('.k_minicolors_swatch'),
            grid = minicolors.find('.k_minicolors_grid'),
            slider = minicolors.find('.k_minicolors_slider'),
            opacitySlider = minicolors.find('.minicolors_opacity_slider'),
            gridPicker = grid.find('[class$=_picker]'),
            sliderPicker = slider.find('[class$=_picker]'),
            opacityPicker = opacitySlider.find('[class$=_picker]');

        if (!hex) {
            hex = convertCase(parseHex(settings.defaultValue, true), settings.letterCase);
        }
        hsb = hex2hsb(hex);

        if (settings.opacity) {
            if (isNaN(opacity)) {
                opacity = 1;
            }
            swatch.find('SPAN').css('opacity', opacity);
            y = keepWithin(opacitySlider.height() - (opacitySlider.height() * opacity), 0, opacitySlider.height());
            opacityPicker.css('top', y + 'px');
        }

        swatch.find('SPAN').css('backgroundColor', hex);

        var _pos;
        switch (settings.control) {
            case 'wheel':

                r = keepWithin(Math.ceil(hsb.s * 0.75), 0, grid.height() / 2);
                phi = hsb.h * Math.PI / 180;
                x = keepWithin(75 - Math.cos(phi) * r, 0, grid.width());
                y = keepWithin(75 - Math.sin(phi) * r, 0, grid.height());
                _pos = {
                    top: y + 'px',
                    left: x + 'px'
                };

                y = 150 - (hsb.b / (100 / grid.height()));
                if (hex === '') {
                    y = 0;
                }
                sliderPicker.css('top', y + 'px');

                slider.css('backgroundColor', hsb2hex({
                    h: hsb.h,
                    s: hsb.s,
                    b: 100
                }));
                break;

            case 'saturation':
                x = keepWithin((5 * hsb.h) / 12, 0, 150);
                y = keepWithin(grid.height() - Math.ceil(hsb.b / (100 / grid.height())), 0, grid.height());
                _pos = {
                    top: y + 'px',
                    left: x + 'px'
                };
                y = keepWithin(slider.height() - (hsb.s * (slider.height() / 100)), 0, slider.height());
                sliderPicker.css('top', y + 'px');

                slider.css('backgroundColor', hsb2hex({
                    h: hsb.h,
                    s: 100,
                    b: hsb.b
                }));
                minicolors.find('.minicolors-grid-inner').css('opacity', hsb.s / 100);
                break;

            case 'brightness':

                x = keepWithin((5 * hsb.h) / 12, 0, 150);
                y = keepWithin(grid.height() - Math.ceil(hsb.s / (100 / grid.height())), 0, grid.height());
                _pos = {
                    top: y + 'px',
                    left: x + 'px'
                };
                y = keepWithin(slider.height() - (hsb.b * (slider.height() / 100)), 0, slider.height());
                sliderPicker.css('top', y + 'px');

                slider.css('backgroundColor', hsb2hex({
                    h: hsb.h,
                    s: hsb.s,
                    b: 100
                }));
                minicolors.find('.minicolors-grid-inner').css('opacity', 1 - (hsb.b / 100));
                break;

            default:
                x = keepWithin(Math.ceil(hsb.s / (100 / grid.width())), 0, grid.width());
                y = keepWithin(grid.height() - Math.ceil(hsb.b / (100 / grid.height())), 0, grid.height());
                _pos = {
                    top: y + 'px',
                    left: x + 'px'
                };
                y = keepWithin(slider.height() - (hsb.h / (360 / slider.height())), 0, slider.height());
                sliderPicker.css('top', y + 'px');
                grid.css('backgroundColor', hsb2hex({
                    h: hsb.h,
                    s: 100,
                    b: 100
                }));
                break;
        }
        gridPicker.css(_pos);
    }

    function updateControl(input, target) {
        var hue, saturation, brightness, x, y, r, phi,
            hex,
            opacity = input.attr('data-opacity'),
            minicolors = this.jqObj,
            settings = this.opts,
            swatch = minicolors.find('.k_minicolors_swatch'),

            grid = minicolors.find('.k_minicolors_grid'),
            slider = minicolors.find('.k_minicolors_slider'),
            opacitySlider = minicolors.find('.k_minicolors_opacity_slider'),

            gridPicker = grid.find('[class$=_picker]'),
            sliderPicker = slider.find('[class$=_picker]'),
            opacityPicker = opacitySlider.find('[class$=_picker]'),

            gridPos = getCoords(gridPicker, grid),
            sliderPos = getCoords(sliderPicker, slider),
            opacityPos = getCoords(opacityPicker, opacitySlider),
            fontColor = "#000000";

        if (input.val) {
            hex = input.val();
        }

        if (target.is('.k_minicolors_grid, .k_minicolors_slider')) {
            switch (settings.control) {
                case 'wheel':
                    x = (grid.width() / 2) - gridPos.x;
                    y = (grid.height() / 2) - gridPos.y;
                    r = Math.sqrt(x * x + y * y);
                    phi = Math.atan2(y, x);
                    if (phi < 0) {
                        phi += Math.PI * 2;
                    }
                    if (r > 75) {
                        r = 75;
                        gridPos.x = 69 - (75 * Math.cos(phi));
                        gridPos.y = 69 - (75 * Math.sin(phi));
                    }
                    saturation = keepWithin(r / 0.75, 0, 100);
                    hue = keepWithin(phi * 180 / Math.PI, 0, 360);
                    brightness = keepWithin(100 - Math.floor(sliderPos.y * (100 / slider.height())), 0, 100);
                    hex = hsb2hex({
                        h: hue,
                        s: saturation,
                        b: brightness
                    });
                    slider.css('backgroundColor', hsb2hex({
                        h: hue,
                        s: saturation,
                        b: 100
                    }));
                    break;
                case 'saturation':
                    hue = keepWithin(parseInt(gridPos.x * (360 / grid.width()), 10), 0, 360);
                    saturation = keepWithin(100 - Math.floor(sliderPos.y * (100 / slider.height())), 0, 100);
                    brightness = keepWithin(100 - Math.floor(gridPos.y * (100 / grid.height())), 0, 100);
                    hex = hsb2hex({
                        h: hue,
                        s: saturation,
                        b: brightness
                    });
                    slider.css('backgroundColor', hsb2hex({
                        h: hue,
                        s: 100,
                        b: brightness
                    }));
                    minicolors.find('.k_minicolors_grid_inner').css('opacity', saturation / 100);
                    break;
                case 'brightness':
                    hue = keepWithin(parseInt(gridPos.x * (360 / grid.width()), 10), 0, 360);
                    saturation = keepWithin(100 - Math.floor(gridPos.y * (100 / grid.height())), 0, 100);
                    brightness = keepWithin(100 - Math.floor(sliderPos.y * (100 / slider.height())), 0, 100);
                    hex = hsb2hex({
                        h: hue,
                        s: saturation,
                        b: brightness
                    });
                    slider.css('backgroundColor', hsb2hex({
                        h: hue,
                        s: saturation,
                        b: 100
                    }));
                    minicolors.find('.k_minicolors_grid_inner').css('opacity', 1 - (brightness / 100));
                    break;
                default:
                    hue = keepWithin(360 - parseInt(sliderPos.y * (360 / slider.height()), 10), 0, 360);
                    saturation = keepWithin(Math.floor(gridPos.x * (100 / grid.width())), 0, 100);
                    brightness = keepWithin(100 - Math.floor(gridPos.y * (100 / grid.height())), 0, 100);
                    hex = hsb2hex({
                        h: hue,
                        s: saturation,
                        b: brightness
                    });
                    grid.css('backgroundColor', hsb2hex({
                        h: hue,
                        s: 100,
                        b: 100
                    }));
                    break;
            }
        }
        if (target.is('.k_minicolors_opacity_slider')) {
            if (settings.opacity) {
                opacity = parseFloat(1 - (opacityPos.y / opacitySlider.height())).toFixed(2);
            } else {
                opacity = 1;
            }
            if (settings.opacity) {
                input.attr('data-opacity', opacity);
            }
        }
        swatch.find('SPAN').css({
            backgroundColor: hex,
            opacity: opacity
        });
        doChange.call(this, hex, opacity, fontColor);
    }

    function doChange(hex, opacity, fontColor) {
        if(hex.indexOf("rgb") > -1){
            hex = hex.toHexColor();
        }
        var input = this.target;
        var settings = this.opts,
            lastChange = input.data('minicolors-lastChange');
        fontColor =    this.getContrastColor(hex);
        var _css = {
            "color": fontColor,
            "background-color": hex,
            filter: 'alpha(opacity=' + opacity * 100 + ')',
            "-moz-opacity": opacity,
            "-khtml-opacity": opacity,
            opacity: opacity
        };
        this.values = _css;
        if (settings.update2Target) {
            this.target.css(_css);
        }
        if (this.target[0].tagName === "INPUT") {
            this.target.val(hex);
        }
        if (!lastChange || lastChange.hex !== hex || lastChange.opacity !== opacity) {
            input.data('minicolors-lastChange', {
                hex: hex,
                opacity: opacity
            });
            if(hex !== "transparent"){
                this.currentColor = hex;    
            }                   
            if (settings.change) {
                settings.change.call(input, hex, opacity);
            }
        }
    }

    function move(target, event, animate) {
        if (!this.target) {
            return;
        }
        var input = this.target,
            _this = this,
            settings = this.opts,
            Picker = target.find('[class$=_picker]'),
            offsetX = target.offset().left,
            offsetY = target.offset().top,
            x = Math.round(event.pageX - offsetX),
            y = Math.round(event.pageY - offsetY),
            duration = animate ? settings.animationSpeed : 0,
            wx, wy, r, phi;

        if (event.originalEvent.changedTouches) {
            x = event.originalEvent.changedTouches[0].pageX - offsetX;
            y = event.originalEvent.changedTouches[0].pageY - offsetY;
        }

        if (x < 0) {
            x = 0;
        }
        if (y < 0) {
            y = 0;
        }
        if (x > target.width()) {
            x = target.width();
        }
        if (y > target.height()) {
            y = target.height();
        }

        if (target.parent().is('.k_minicolors_slider_wheel') && Picker.parent().is('.k_minicolors_grid')) {
            wx = 75 - x;
            wy = 75 - y;
            r = Math.sqrt(wx * wx + wy * wy);
            phi = Math.atan2(wy, wx);
            if (phi < 0) {
                phi += Math.PI * 2;
            }
            if (r > 75) {
                r = 75;
                x = 75 - (75 * Math.cos(phi));
                y = 75 - (75 * Math.sin(phi));
            }
            x = Math.round(x);
            y = Math.round(y);
        }
        if (target.is('.k_minicolors_grid')) {
            Picker.stop(true).animate({
                top: y + 'px',
                left: x + 'px'
            }, duration, settings.animationEasing, function () {
                updateControl.call(_this, input, target);
            });
        } else {
            Picker.stop(true).animate({
                top: y + 'px'
            }, duration, settings.animationEasing, function () {
                updateControl.call(_this, input, target);
            });
        }
        return false;
    }

    function ColorPicker(jqObj, opts) {
        $B.extend(this, ColorPicker); //继承父类        
        this.lastColors = [];//最近使用的颜色
        this.colorCookieName = "colorpicker_";
        var seft = this;
        this.opts = $.extend(true, {}, defaults, opts);
        if (jqObj) {
            this.setTarget(jqObj);
        }
        this.jqObj = $('<div tabindex="0" class="k_minicolors k_box_shadow" />')
            .addClass('k_minicolors_theme_' + this.opts.theme)
            .toggleClass('k_minicolors_with_opacity', this.opts.opacity).appendTo($("body"));
        this.jqObj.append(
            '<div tabindex="0" class="k_minicolors_panel  k_minicolors_slider_' + this.opts.control + '">' +
            '<div tabindex="0" class="k_minicolors_slider"><div class="k_minicolors_picker"></div>' +
            '</div><div tabindex="0"  class="k_minicolors_opacity_slider"><div  tabindex="0"  class="k_minicolors_picker"></div>' +
            '</div><div  tabindex="0" class="k_minicolors_grid"><div  tabindex="0"  class="k_minicolors_grid_inner"></div>' +
            '<div tabindex="0" class="k_minicolors_picker"><div  tabindex="0" ></div></div></div></div>');
        if (this.opts.showCaret) {
            $("<div style='height:12px;width:100%;margin-top:-12px;padding-left:2px'><i style='font-size:16px;color:#3E4043;line-height:12px;position:relative;top:1px' class='fa fa-up-dir'></i></div>").prependTo(this.jqObj);
        }
        this.isBodyClick = true;
        this.jqObj.children(".k_minicolors_panel").mousedown(function () {
            $doc.data("_colorpicker_", seft);
            $doc.on('mousedown.k_minicolors touchstart.k_minicolors', '.k_minicolors_grid, .k_minicolors_slider, .k_minicolors_opacity_slider',
                function (event) {
                    var target = $(this);
                    var _this = $doc.data('_colorpicker_');
                    $doc.data('k_minicolors_target', target);
                    move.call(_this, target, event, true);
                    if (_this.opts.onStartFn) {
                        _this.opts.onStartFn();
                    }
                }).on('mousemove.k_minicolors touchmove.k_minicolors',
                    function (event) {
                        var _this = $doc.data('_colorpicker_');
                        var target = $doc.data('k_minicolors_target');
                        if (target) {
                            move.call(_this, target, event);
                        }
                    }).on('mouseup.k_minicolors touchend.k_minicolors',
                        function (event) {
                            var _this = $doc.data('_colorpicker_');
                            if (_this) {
                                var target = $doc.data('k_minicolors_target');
                                if (target) {
                                    $(this).removeData('k_minicolors_target');
                                    if (_this.opts.onEndFn) {
                                        _this.opts.onEndFn();
                                    }
                                }
                                _this.isBodyClick = false;
                                setTimeout(function () {
                                    _this.isBodyClick = true;
                                }, 300);
                            }
                        });

        }).mouseup(function () {
            $doc.off('mousedown.k_minicolors touchstart.k_minicolors', '.k_minicolors_grid, .k_minicolors_slider, .k_minicolors_opacity_slider');
            setTimeout(function () {
                $doc.removeData("_colorpicker_");
            }, 300);
        });
        this.colorsBtnWrap = $("<div  tabindex='0'  class='k_minicolors_color_buttons'></div>").appendTo(this.jqObj);
        function _click() {
            seft.target.removeData('minicolors-lastChange');
            seft.buttonClick($(this).css("background-color"));
        }
        for (var i = 0, len = this.opts.buttons.length; i < len; ++i) {
            var $btn = $("<div  tabindex='0' style='background-color:" + this.opts.buttons[i] + "'></div>")
                .appendTo(this.colorsBtnWrap)
                .click(_click);
            if (i === 0) {
                $btn.addClass("k_mincolors_btn_nonecolor");
            }
        }
        if (this.opts.onfocus) {
            this._bindFocus(this.jqObj);
        }
        if (this.opts.mouseenter) {
            this.jqObj.mouseenter(this.opts.mouseenter);
        }
        if (this.opts.clickHide) {
            (function (_this) {
                var nsId = $B.getUUID();
                $("body").on("click."+nsId,function(){
                    if (_this.isBodyClick) {
                        _this.hide();
                    }else{
                        $(this).off("."+nsId);
                    }
                });               
            })(seft);
        }
        //从cookie恢复最近使用的5个颜色
        var tmp = $B.getCookie(this.colorCookieName);
        if(tmp !== ""){
            var colors = tmp.split(",");
            this.lastColors = colors;
            this._setLastColors();
        }
    }
    ColorPicker.prototype = {
        constructor: ColorPicker,
        /**获取高对比度颜色**/
        getContrastColor:function(value){
            if(!value){
                return 'rgb(105, 118, 166)';
            }
            var rgb = value;
            if (value.toLowerCase().indexOf("rgb") < 0) {
                rgb = hex2rgb(value);
            }
            rgb.r = 255- rgb.r;
            rgb.g = 255- rgb.g;
            rgb.b = 255- rgb.b;
            return ['rgb(',rgb.r,',',rgb.g ,',',rgb.b,')'].join('');         
        },
        _bindFocus: function (jqTag) {
            var _this = this;
            var _onfocus = function (e) {
                _this.opts.onfocus();
            };
            jqTag.on("focus", _onfocus);
            jqTag.children().each(function () {
                _this._bindFocus($(this));
            });
        },
        setTarget: function (jqObj) {
            this.target = jqObj.css("background-image", "none").addClass("k_color_picker_cls");
            if (!this.target.data("color_picker_fire")) {
                this.target.on("click.colorpicker", function (e) {
                    var $t = $(this);
                    if ($t.data("break")) {
                        return;
                    }
                    var picker = $t.data("picker");
                    if (picker.isShow()) {
                        picker.hide();
                    } else {
                        picker.show();
                    }
                }).data("picker", this);
                this.target.data("color_picker_fire", true);
            }
            return this;
        },
        unbindTarget: function () {
            if (this.target) {
                this.target.removeData("color_picker_fire");
                this.target.removeData("picker");
                this.target.off("click.colorpicker").removeClass("k_color_picker_cls");
                this.target = undefined;
            }
            return this;
        },
        setPosition: function (ofs) {
            ofs.top = ofs.top + this.target.outerHeight();
            if (this.opts.positionFix) {
                if (this.opts.positionFix.top) {
                    ofs.top = ofs.top + this.opts.positionFix.top;
                }
                if (this.opts.positionFix.left) {
                    ofs.left = ofs.left + this.opts.positionFix.left;
                }
            }
            this.jqObj.css(ofs).show();
            return this;
        },
        hideImd: function (isUnbind) {
            var _this = this;
            if (isUnbind) {
                _this.unbindTarget();
            }
            _this.jqObj.hide();
            if (_this.opts.onHideFn) {
                _this.opts.onHideFn();
            }
        },
        hide: function (isUnbind) {
            if(this.currentColor){
                if(this.currentColor.indexOf("rgb") > -1){
                    this.currentColor = this.currentColor.toHexColor();
                }
                this.currentColor = this.currentColor.toLowerCase();
                var i = 0 ,len ,go = true;
                for( i = 0 ,len = this.lastColors.length ; i < len ;++i){
                    if(this.currentColor === this.lastColors[i]){
                        go = false;
                        break;
                    }
                }
                if(go){
                    //记住最近用的5种颜色
                    if(this.lastColors.length === 5){
                        this.lastColors.pop();                          
                    }
                    this.lastColors.unshift(this.currentColor); 
                    this._setLastColors();
                }                
            }
            this.currentColor = undefined;
            clearTimeout(this["hidetimer"]);
            var _this = this;
            this["hidetimer"] = setTimeout(function () {
                if (isUnbind) {
                    _this.unbindTarget();
                }
                _this.jqObj.slideUp(100, function () {
                    if (_this.opts.onHideFn) {
                        _this.opts.onHideFn();
                    }
                });
            }, 100);
            return this;
        },
        _setLastColors:function(){
            //更新 this.colorsBtnWrap
            var lastBtn = this.colorsBtnWrap.children().last();
            for(var i = 0 ,len = this.lastColors.length ; i < len ;++i){
                lastBtn.css("background-color" , this.lastColors[i]);
                lastBtn = lastBtn.prev();
            }
            var lastColorstr = this.lastColors.join(",");
            $B.writeCookie(this.colorCookieName , lastColorstr ,3);
        },
        show: function (target, offset) {
            if (this.target && target && this.target[0] === target[0]) {
                return;
            }
            clearTimeout(this["showtimer"]);
            var _this = this;
            if (target) {
                target.data("break", true);
                _this.setTarget(target);
            }
            var ofs = _this.target.offset();
            if (offset) {
                if (offset.top) {
                    ofs.top = ofs.top + offset.top;
                }
                if (offset.left) {
                    ofs.left = ofs.left + offset.left;
                }
            }
            this["showtimer"] = setTimeout(function () {
                _this.setPosition(ofs);
                _this.target.removeData("break");
            }, 200);
            return this;
        },
        isShow: function () {
            var dis = this.jqObj.css("display");
            return dis === "block";
        },
        buttonClick: function (color) {
            doChange.call(this, color, 1, undefined);           
            if (typeof color === "string") {
                if (color.toLowerCase().indexOf("rgb") > -1) {
                    color = color.toHexColor();
                }
                var value = {
                    "hex": color
                };
                updateFromInput.call(this, value);
            }            
            return this;
        },
        /**
         * {hex:,opacity:}
         * **/
        setValue: function (value, invokeChange) {
            if (typeof value === "string") {
                if (value.toLowerCase().indexOf("rgb") > -1) {
                    value = value.toHexColor();
                }
                value = {
                    "hex": value
                };
            }
            updateFromInput.call(this, value);
            if (this.target && (typeof invokeChange === "undefined" || invokeChange)) {
                doChange.call(this, value.hex, 1, undefined);
            }
            return this;
        },
        getValue: function () {
            return this.values;
        }
    };
    $B["ColorPicker"] = ColorPicker;
    return ColorPicker;
}));(function (global, factory) {
    if (typeof define === 'function' && define.amd) {
        define(['$B', 'tree'], function (_$B) {
            return factory(global, _$B);
        });
    } else {
        if(!global["$B"]){
            global["$B"] = {};
        }
        factory(global, global["$B"]);
    }
}(typeof window !== "undefined" ? window : this, function (window, $B) {
    var $body;
    function _getBody(){
        if(!$body){
            $body = $(window.document.body).css("position", "relative");
        }
        return $body;        
    }
    var defaultOpts = {
        data: [], //数据 参考树数据
        default: {
            id: '',
            text: $B.config.comboxPlaceholder
        }, //默认选择项目
        mutilChecked: true, //是否多选
        checkfather: false, //是否可以选择父节点
        onlyNodeData: true, //是否仅节点数据（不包含children）
        tree2list: true,
        initShow: false, //初始化时候是否显示下拉列表
        isTreeData: true, //是否是树形数据
        placeholder: $B.config.comboxPlaceholder,
        plainStyle: true, //true 为简单无图标样式
        extParamFiled: [], //异步加载时候，可以定义再传一个字段作为参数，默认不设置只传pid 
        search: undefined, //模糊搜索类型 remote/local  
        localSearchFiled: ['text'], //本地搜索的字段，默认只有一个text,可以设置多个字段
        url: '', //模糊查询自动完成时候的请求路径
        readonly: true, //不可以编辑
        textField: 'text', //菜单名称字段，默认为text
        idField: 'id', //菜单id字段,默认为id               
        onCheck: null, //点击事件 =function(data) data为当前选择的数据 ,可以不注册该事件，组件内部已经将数据赋值到input的 value 和 data-key属性中                 
        onClick: null //点击事件，点击后会自动收起，如果想点击后还不收起 请使用oncheck
    };

    function Combox(jqObj, opts) {
        $B.extend(this, Combox);        
        var _this = this;
        this.jqObj = jqObj.addClass("k_combox_input").wrap("<div class='k_combox_input_wrap'></div>");
        setTimeout(function(){
            _this.jqObj.off("mouseover.textbox");
            _this.jqObj.off("mouseout.textbox");
            _this.jqObj.off("input.textbox");
        },500);
        this.jqObj.attr("autocomplete","off");
        this.iptWrap = this.jqObj.parent();
        this.width = this.jqObj.outerWidth();
        this.height = this.jqObj.outerHeight();
        if(this.width === 0 || this.height === 0){
            var _ivt = setInterval(function(){
                _this.width = _this.jqObj.outerWidth();
                _this.height = _this.jqObj.outerHeight();
                if(_this.width !== 0 || _this.height !== 0){
                    clearInterval(_ivt);                   
                    _this.size.width = _this.width;
                    _this.size.height = _this.height - 1;
                    _this.icon.css("left",_this.size.width - 12);
                    _this.dropList.children("ul").css("min-width",_this.width);
                    _this._fixLeftTop();
                }
            },200);
        }
        this.opts = $.extend({}, defaultOpts, opts);
        var chickFn = this.opts.onClick;        
        this.opts.onClick = function (datas, params) { //点击单选事件
            var nodeData = datas[0];
            var data = nodeData.data;
            if (!_this.opts.mutilChecked) {
                if (_this.opts.checkfather === false && params.isParent) { } else {
                    var id = nodeData[_this.opts.idField],
                        text = nodeData[_this.opts.textField];
                    if (typeof id === "undefined") {
                        id = data[_this.opts.idField];
                    }
                    if (!text) {
                        text = data[_this.opts.textField];
                    }
                    _this.jqObj.val(text).data("id", id);
                    if(typeof _this.onWatcher === "function"){//配合动态双向表单功能
                        _this.onWatcher.call(_this);
                    }
                    _this._fireValidFn();
                }
            }
            _this.hide(function () {
                if (typeof chickFn === 'function') {
                    setTimeout(function () {
                        try {
                            chickFn(data);
                        } catch (ex) {
                            _this.error("onClick is error " + ex.message);
                        }
                    }, 1);
                }
            });
        };
        this._onCheckFn = this.opts.onCheck;
        //var closedTimer;
        this.opts.onCheck = function (data, params, checked) {//多选事件
            _this._setInputValue();
            if (typeof _this._onCheckFn === "function") {
                setTimeout(function () {
                    _this._onCheckFn.call(_this, data, params, checked);
                }, 1);
            }
            if(typeof _this.onWatcher === "function"){//配合动态双向表单功能
                _this.onWatcher.call(_this);
            }            
        };
        this.opts.checkbox = this.opts.mutilChecked === true;
        this.size = {
            width: this.jqObj.outerWidth(),
            height: this.jqObj.outerHeight() - 1
        };
        if (!_this.opts.isTree) {
            this.opts.plain = true;
        }
        this.body = $(document.body).css('position', 'relative');
        var $win = $(window);
        var nsId = $B.getUUID();
        $win.on("resize."+nsId,function(){
            if(_this.repositon){
                _this.repositon();
            }else{
                $(this).off("."+nsId);
            }  
        });
        $win.on("click."+nsId,function(){
            if(_this.hide){
                _this.hide();
            }else{
                $(this).off("."+nsId);
            } 
        });       
        //var id = this.jqObj.attr("id");
        var border_color = this.jqObj.css("border-color");
        this.dropList = $("<div class='k_box_size k_combox_wrap' style='z-index: 2147483647;position:abosulte;top:-100000px;min-width:" + this.size.width + "px;border-color:" + border_color + ";'><ul></ul></div>").appendTo(this.body).hide();
        this.dropList.data("direction", "d").data("combox", this);
        this.jqObj.on({
            click: function () {
                if (_this.dropList.css("display") === 'none') {
                    _this.show();
                } else {
                    _this.hide();
                }
                return false;
            }
        }).attr("placeholder", this.opts.placeholder);
        this.jqObj.val(this.opts.default.text).data("id", this.opts.default.id);
        this._createTree();
        setTimeout(function () {
            _this.repositon();
        }, 1);        
        if (this.opts.readonly === true) {
            this.jqObj.attr("readonly", "readonly").css("cursor", "pointer");
        }
        this.icon = $("<div style='top:4px;left:" + (this.width - 12) + "px;background:none;' class='k_tree_combox k_combox_input_icon btn'><i style='font-size:14px;float:right;padding-right:3px;font-size:12px;margin-top:5px;' class='fa fa-down-dir'></i></div>").appendTo(this.iptWrap);
        this.icon.click(function () {
            _this.jqObj.trigger("click");
            return false;
        });
        var timer;
        this.initing = true;
        //开启输入模糊匹配localSearchFiled
        if (!this.opts.readonly && this.opts.search) {
            this.jqObj.on("input", function () {
                if (_this.tree && !_this.initing) {
                    var txt = $.trim(_this.jqObj.val().replace(/'/g, ''));
                    clearTimeout(timer);
                    if ($B.isUrl(_this.opts.url) && _this.opts.search === "remote") {
                        timer = setTimeout(function () {
                            _this.tree.reload(_this.dropList.children("ul"), {
                                keyword: txt
                            });
                        }, 500);
                    } else { //本地搜索
                        timer = setTimeout(function () {
                            _this._localSearch(txt);
                        }, 500);
                    }
                }
            });
        }
        this.jqObj.data("combox", this);        
        // var closedTimer ; 
        // this.dropList.on("mouseleave",function(){            
        //     closedTimer = setTimeout(function(){
        //         _this.hide();
        //     }, 1500);
        // }).on("mouseenter",function(){
        //     clearTimeout(closedTimer);            
        // });   
        this.jqObj.mouseenter(function(){
            var  $s = $(this);
            $s.attr("title",$s.val());
        });     
    }
    Combox.prototype = {
        constructor: Combox,
        _setInputValue: function (isImd) {
            var _this = this;    
            var data,id,text;        
            if(_this.opts.checkbox){
                var prs = {
                    onlyChild: !_this.opts.checkfather
                };
                data = _this.tree.getCheckedData(prs);                
                var setFn = function () {
                    var idArr = [],
                        txtArr = [];
                    for (var i = 0, l = data.length; i < l; ++i) {
                        var one = data[i];
                        id = one[_this.opts.idField];
                        text = one[_this.opts.textField];
                        if (!id) {
                            id = one.data[_this.opts.idField];
                        }
                        if (!text) {
                            text = one.data[_this.opts.textField];
                        }
                        idArr.push(id);
                        txtArr.push(text);
                    }
                    _this.jqObj.val(txtArr.join(",")).data("id", idArr.join(","));
                    _this._fireValidFn();
                };
                if(isImd){
                    setFn();
                }else{
                    clearTimeout( _this._setInputValueTimer);
                    _this._setInputValueTimer = setTimeout(setFn,100);
                }              
            }else{
                if(this.tree.clickedItem){
                    data = this.tree.clickedItem.data("data");
                    id = data[_this.opts.idField],
                    text = data[_this.opts.textField];
                    _this.jqObj.val(text).data("id", id);
                }else{
                    this.jqObj.val(this.opts.default.text).data("id", this.opts.default.id);
                }
                _this._fireValidFn();
                //console.log("单选模式");
            }
        },
        /***触发验证***/
        _fireValidFn:function(){
            var _this = this;
            setTimeout(function(){
                _this.jqObj.trigger("mouseleave.kvalidate");
            },200);
        },
        _localSearch: function (txt) {
            if (this.dropList.css("display") === "none") {
                this.show();
            }
            this.tree.jqObj.children("._nodata_tip").remove();
            var i, len, c, p, wrap, ul, clickNode;
            var childs = this.tree.childNodesArray;
            var parents = this.tree.parentNodesArray;
            var deep = 0,
                tmpDeep, showParents;
            for (i = 0, len = parents.length; i < len; ++i) {
                p = parents[i].show();
                wrap = p.children("div");
                tmpDeep = parseInt(wrap.attr("deep"));
                if (tmpDeep > deep) {
                    deep = tmpDeep;
                }
                ul = p.children("ul");
                if (ul.css("display") === "none") {
                    clickNode = wrap.children("._line_node_");
                    if (clickNode.length === 0) {
                        clickNode = wrap.children("._node_");
                    }
                    clickNode.trigger("click");
                }
            }
            for (i = 0, len = childs.length; i < len; ++i) {
                c = childs[i];
                var data = c.children("div").data("data");
                if (this._isLike(data, txt)) {
                    c.show();
                } else {
                    c.hide();
                }
            }
            this._fixLeftTop();
            //修正父元素的显示
            deep++;
            while (deep > 0) {
                showParents = [];
                for (i = 0, len = parents.length; i < len; ++i) {
                    p = parents[i].show();
                    wrap = p.children("div");
                    ul = p.children("ul");
                    if (ul.height() === 0) {
                        p.hide();
                    } else {
                        showParents.push(p);
                    }
                }
                parents = showParents;
                deep--;
            }
            if (this.tree.jqObj.height() === 0) {
                var $li = $("<li class='_nodata_tip'>" + $B.config.noData + "</li>").appendTo(this.tree.jqObj);
                setTimeout(function () {
                    try {
                        $li.remove();
                    } catch (ex) { }
                }, 3000);
            }
        },
        _isLike: function (nodeData, txt) {
            if (txt === "") {
                return true;
            }
            var isLike = false;
            for (var i = 0, len = this.opts.localSearchFiled.length; i < len; i++) {
                var filed = this.opts.localSearchFiled[i];
                if (nodeData[filed] && nodeData[filed].indexOf(txt) >= 0) {
                    isLike = true;
                    break;
                }
                if (!isLike) {
                    if (nodeData.data[filed] && nodeData.data[filed].indexOf(txt) >= 0) {
                        isLike = true;
                        break;
                    }
                }
            }
            return isLike;
        },
        _createTree: function () {
            var _this = this;
            if (this.opts.data.length === 0 && this.opts.url !== "") {               
                this.jqObj.val("");
                this.jqObj.attr("placeholder", $B.config.loading);
                this.ajax({
                    url: this.opts.url,
                    ok: function (data, message) {
                        _this.opts.data = data;
                        _this._bindTree();
                    },
                    fail: function (message) { },
                    final: function (res) {
                        _this.jqObj.val(_this.opts.default.text).data("id", _this.opts.default.id);
                        _this.jqObj.attr("placeholder", $B.config.comboxPlaceholder);
                        if(_this.opts.onReqloaded){
                            _this.opts.onReqloaded(res);
                        }
                    }
                });
            } else {
                this._bindTree();
            }
        },
        _isFined:function(defId,datas){
            var go = true;
            for(var i = 0 ,len = datas.length ; i < len ; ++i){
                if(datas[i].id === defId){
                    go = false;
                    break;
                }
                if(datas[i].children){
                    go = this._isFined(defId,datas[i].children);
                    if(!go){
                        break;
                    }
                }
            }
            return go;
        },
        _bindTree: function () {
            if (!$.isEmptyObject(this.opts.default)) {
                if (!this.opts.default["data"]) {
                    this.opts.default["data"] = {};
                }
                if (this.opts.default.text !== '') {
                    /***树形递归检查数据项已经存在****/
                    var go = this._isFined(this.opts.default.id,this.opts.data);
                    if(go){
                        this.opts.data.unshift(this.opts.default);
                    }                   
                }
            }
            var isLocalSearch = this.opts.search && this.opts.search === "local";
            this.opts.isLocalSearch = isLocalSearch;
            var _this = this;
            this.opts.onTreeCreated = function () {
                if( _this.initing){
                    _this._setInputValue();
                    if (_this.opts.initShow) {
                        _this.show();
                    } else {
                        _this.hide();
                    }
                }               
                _this.initing = false;
            };
            this.opts.onToggle = function () {
                _this._fixLeftTop();
            };
            this.opts.onloaded = function(){
                _this._setInputValue();
            };
            this.tree = new $B.Tree(this.dropList.children("ul"), this.opts);           
            if(!this.opts.mutilChecked){
                setTimeout(function(){
                    _this.tree.setClickedItem(_this.opts.default.id);
                },1000);               
            }           
        },
        repositon: function () {
            console.log("fix repositon >>>>>");
            var w = this.body.width(),
                h = this.body[0].scrollHeight;
            var offset = this.jqObj.offset(),
                maxWidth = w - offset.left,
                maxHeight = h - offset.top - this.height,
                topHeight = offset.top;
            this.dropList.data("direction", "d");
            var top = offset.top + this.size.height,
                height;
            this.dropList.css({
                top: top,
                "overflow":'auto',
                left: offset.left,
                "max-width": maxWidth,
                "max-height": maxHeight
            });
        },
        _fixLeftTop: function () {
            var offset = this.jqObj.offset();
            var top = offset.top + this.size.height;
            this.dropList.css({
                top: top,
                left: offset.left
            });
        },
        reset: function () {
            this._setBreakHide();
            this.jqObj.val(this.opts.default.text).data("id", this.opts.default.id);
            this.tree.reset();
        },
        _setBreakHide: function () {
            var _this = this;
            this._breakHide = true;
            setTimeout(function () {
                _this._breakHide = false;
            }, 300);
        },
        getCheckedData: function () {
            this._setBreakHide();
            if(!this.tree){
                return [];
            }
            if (this.opts.mutilChecked) {
                return this.tree.getCheckedData();
            } else {
                return this.tree.getClickItem();
            }
        },
        getCheckedIds: function () {
            this._setBreakHide();
            if(!this.tree){
                return [];
            }
            if (this.opts.mutilChecked) {
                return this.tree.getCheckedData({
                    onlyId: true
                });
            } else {
                var data = this.tree.getCheckedData();
                return data.id;
            }
        },
        hide: function (fn) {
            if (this._breakHide) {
                return;
            }
            if (this.dropList.data("direction") === "d") {
                this.dropList.slideUp(200, function () {
                    if (typeof fn === 'function') {
                        fn();
                    }
                    var _t = this;
                    _getBody().children(".k_combox_wrap").each(function () {
                        if (_t !== this) {
                            $(this).data("combox")._fixLeftTop();
                        }
                    });
                });
            } else {
                this.dropList.hide();
                if (typeof fn === 'function') {
                    fn();
                }
            }
            if (this.icon) {
                this.icon.children().addClass("fa-down-dir").removeClass("fa-up-dir").css("margin-top", "5px");
            }
        },
        show: function () {
            var _this = this;
            this.repositon();           
            if (this.dropList.data("direction") === "d") {
                this.dropList.slideDown(200, function () {
                    _this._fixLeftTop();
                    var _t = this;
                    _getBody().children(".k_combox_wrap").each(function () {
                        if (_t !== this) {
                            $(this).data("combox")._fixLeftTop();
                        }
                    });
                });
            } else {
                this.dropList.css({
                    "display": "block",
                    "top": 0
                });
            }
            if (this.icon) {
                this.icon.children().removeClass("fa-down-dir").addClass("fa-up-dir").css("margin-top", "5px");
            }
        },
        val:function(){
           return this.jqObj.data("id");
        },
        /**
         * 设置勾选/选择的数据，适配mvvm联动
         * datas = []; datas = "id1,id2,id3"
         * ***/
        setCheckDatas:function(datas){ 
            if(this.tree){
                if(this.opts.mutilChecked){
                    this.tree.setCheckDatas(datas);          
                }else{
                    this.tree.setClickedItem(datas);
                }
                this._setInputValue(true);
            }           
        },
        /**重写destroy**/
        destroy: function () {
            this.dropList.remove();
            this["super"].destroy.call(this);
        }
    };
    $B["Combox"] = Combox;
    return Combox;
}));(function (global, factory) {
    if (typeof define === 'function' && define.amd) {
        define(['$B'], function (_$B) {
            return factory(global, _$B);
        });
    } else {
        if(!global["$B"]){
            global["$B"] = {};
        }
        factory(global, global["$B"]);
    }
}(typeof window !== "undefined" ? window : this, function (window, $B) {
    var document = window.document;
    var $body;
    function _getBody(){
        if(!$body){
            $body = $(document.body).css("position", "relative");
        }
        return $body;        
    }
    /***全局关闭***/
    var hasIns = false;   
    var shouldClosed = true;
    window["_ctxmenu_close_fn"] = function(){
        if(hasIns && shouldClosed){
            var moreWraps = $("body").children(".k_context_menu_container");      
            moreWraps.hide();
        }        
    };     
    $(window).on('mouseup._ctxmenu_close_fn', function () { 
        if(hasIns){
            window["_ctxmenu_close_fn"]();
        }        
        setTimeout(function() {            
            if(window.parent !== window.self && window.parent["_ctxmenu_close_fn"]){              
                window.parent["_ctxmenu_close_fn"]();
            }
        }, 10);
    });     
    function Ctxmenu(jqObj, opts) {
        hasIns = true;
        $B.extend(this, Ctxmenu);
        this.$body = _getBody();
        var _this = this;
        this.$body.css('position', 'relative').on('click', function (e) {
            _this.$body.children(".k_context_menu_container").remove();
            return false;
        });
        if (arguments.length === 1) {
            this.jqObj = this.$body;
            this.opts = arguments[0];
        } else {
            this.jqObj = jqObj;
            this.opts = opts;
        }
        this.opts.push({
            text: $B.config.closeLable,
            iconCls: 'fa-minus',
            click: function () {
                _this.$body.children(".k_context_menu_container").remove();
            }
        });
        function _destorySubmenu($cwrap) {
            var submenu = $cwrap.data("submenu");
            if (submenu) {
                submenu.remove();
                $cwrap.removeData("submenu");
            }
        }
        var createItem = function (opt, $wrap) {
            var $it = $('<div class="k_context_menu_item_cls"><span class="k_context_menu_item_ioc"><i class="k_ctxmenu_i fa ' + opt.iconCls + '"></i></span><span class="k_context_menu_item_txt">' + opt.text + '</span></div>').appendTo($wrap).on({
                click: function () {
                    var _$t = $(this);
                    _$t.parent().remove();
                    if (opt.click) {
                        setTimeout(function () {
                            opt.click.call(_$t);
                        }, 10);
                    }
                }
            });
            if (opt.items) {
                $it.append('<span class="k_context_menu_more_ioc"><i class="fa fa-angle-double-right k_ctxmenu_i"></i></span>');
                $it.mouseenter(function () {
                    var $t = $(this);
                    var _data = $t.data("items");
                    var $cwrap = $wrap.data("submenu");
                    var offset = $t.offset();
                    var left = offset.left + $t.outerWidth() + 3;
                    var top = offset.top;
                    if ($cwrap) {
                        _destorySubmenu($cwrap);
                        $cwrap.children().remove();
                        $cwrap.css({
                            left: left + 'px',
                            top: top + 'px'
                        }).show();
                    } else {
                        $cwrap = $("<div style='position:absolute;z-index:99999999999999999999;height:auto;' class='k_context_menu_container k_box_shadow k_box_radius'/>").appendTo(_this.$body).css({
                            left: left + 'px',
                            top: top + 'px'
                        });
                        $wrap.data("submenu", $cwrap);
                    }
                    for (var i = 0, l = opt.items.length; i < l; ++i) {
                        var _opt = opt.items[i];
                        createItem(_opt, $cwrap);
                    }
                }).data("items", opt.items);
            } else {
                $it.mouseenter(function () {
                    var $t = $(this);
                    var $cwrap = $wrap.data("submenu");
                    if ($cwrap) {
                        $cwrap.hide();
                    }
                });
            }
        };
        this.mousedown = function (e) {
            var left = e.clientX;
            var top = e.clientY;
            _this.$body.children(".k_context_menu_container").remove();
            //2147483647
            var $wrap = $("<div style='position:absolute;z-index:-1000;height:auto;' class='k_context_menu_container k_box_shadow k_box_radius'/>").appendTo(_this.$body).css({
                left: left + 'px',
                top: top + 'px'
            });
            $.each(_this.opts, function () {
                createItem(this, $wrap);
            });
            var width = $wrap.outerWidth();
            var availableWidth = _this.$body.width() - left;
            var diff = availableWidth - width;
            var css = {"z-index":2147483647};
            if(diff < 0){
                css.left = left + diff;               
            }
            $wrap.css(css);
        };
        this.jqObj.on({
            mousedown: function (e) {
                if (3 === e.which) {
                    shouldClosed = false;
                    _this.mousedown(e);
                    setTimeout(function() {
                        shouldClosed = true;
                    },300);
                }
            },mouseup:function(){
                return false;
            }
        });
        _this.$body.on("contextmenu", function (e) {
            return false;
        });
    }
    Ctxmenu.prototype = {
        bandTarget: function (target) {
            var _this = this;
            target.on({
                mousedown: function (e) {
                    if (3 === e.which) {
                        shouldClosed = false;
                        _this.mousedown(e);
                        setTimeout(function() {
                            shouldClosed = true;
                        },300);
                    }
                },
                contextmenu: function (e) {
                    return false;
                }
            });
        },
        hide: function () {
            this.$body.children(".k_context_menu_container").remove();
        }
    };
    $B["Ctxmenu"] = Ctxmenu;
    return Ctxmenu;
}));(function (global, factory) {
    if (typeof define === 'function' && define.amd) {
        define(['$B', 'tree', 'toolbar', "pagination"], function (_$B) {
            return factory(global, _$B);
        });
    } else {
        if (!global["$B"]) {
            global["$B"] = {};
        }
        factory(global, global["$B"]);
    }
}(typeof window !== "undefined" ? window : this, function (window, $B) {
    var $doc = $(document);
    var $body;
    function _getBody() {
        if (!$body) {
            $body = $(window.document.body).css("position", "relative");
        }
        return $body;
    }
    var scrollWidth;
    /**
     *列默认配置
     ***/
    var defaultColOpts = {
        title: '',
        field: '', //字段
        width: 'auto',
        rowspan: 0, // 跨行
        colspan: 0, //跨列
        align: 'left', //对齐'left'、'right'、'center'
        sortable: true, //该列是否可以排序
        resizable: false, //可以调整宽度
        formatter: null //function (cellValue, rowData) {return cellValue }//单元格格式化函数
    };
    /**
     *datagrid全局配置
     ***/
    var defaultOpts = {
        title: '', //标题       
        data: null, //列表数据 存在初始化数据时，优先用初始化数据
        url: '', //url
        fillParent: false, //是否占满父元素(垂直方向)
        loadImd: true, //是否立即加载        
        toolbar: null, //工具栏，参考toolbar组件
        oprCol: true, //是否需要行操作列   
        treeIconColor: undefined,//树形图标颜色  
        oprColWidth: 'auto', //操作列宽度
        cols: [], //列配置，支持多表头
        idField: 'id', //id字段名称        
        checkBox: true, //是否需要复选框
        isTree: false, //是否是树形列表
        pgposition: 'bottom', //分页工具栏位置 top,bottom,both ,none none表示不需要分页栏
        pageSize: 30, //页大小
        page: 1,
        startPage: 1,
        btnStyle: 'plain', //对应工具栏里的style 
        showBtnText: true, //是否显示按钮      
        pgBtnNum: 10, //页按钮数量
        iconCls: undefined, //图标   fa-table
        setParams: undefined, //设置参数
        splitColLine: 'k_datagrid_td_all_line', //分割线样式 k_datagrid_td_v_line、k_datagrid_td_h_line
        pageList: [15, 25, 30, 35, 40, 55, 70, 90, 100], //页大小选择
        sortField: undefined, //默认排序字段
        onDbClickRow: null, // function (data) { },//双击一行时触发 fn(rowData)
        onClickCell: null, // function (field, value) { },//单击一个单元格时触发fn(field, value)
        onCheck: null, //function () { },//复选事件
        onRowRender: null, // function (data) { },//行渲染事件      
        onLoaded: null //function (data) { }//加载完成回调
    };
    var chkbox_w = 25;
    var trEvents = {
        dblclick: function (e) {
            var $t = $(this);
            var _this = $t.data("_this");
            clearTimeout(_this.clickTimer);
            if (typeof _this.opts.onDbClickRow === "function") {
                setTimeout(function () {
                    _this.opts.onDbClickRow.call($t);
                }, 1);
            }
        }
    };
    var tdEvents = {
        mousemove: function (e) {
            var $t = $(this);
            var _this = $t.data("_this");
            if (_this.opts.checkBox) {
                if ($t.position().left < 32) {
                    return true;
                }
            }
            var x = $t.offset().left;
            var endX = $t.width() + x;
            var left = e.pageX;
            $t.css("cursor", "default").removeData("splitX");
            if ((x - 3) <= left && left <= (x + 3)) {
                $t.css("cursor", "w-resize").data("splitX", left);
            } else if ((endX - 3) <= left && left <= (endX + 3)) {
                $t.css("cursor", "w-resize").data("splitX", left);
            }
        },
        mouseover: function (e) {
            var $t = $(this);
            var $txt = $t.children(".k_datagrid_cell_text");
            var txt = $txt.text();
            var len = $B.getCharWidth(txt, $txt.css("font-size"));
            if (len > $txt.width()) {
                $t.attr("title", txt);
            }
        },
        mouseout: function (e) {
        },
        dblclick: function (e) { },
        mousedown: function (e) {
            var $t = $(this);
            var _this = $t.data("_this");
            var splitX = $t.data("splitX");
            if (splitX) {
                var keys = Object.keys(_this.moveXofs);
                var index;
                var scrollLeft = _this.scrollLeft;
                splitX = splitX + scrollLeft;
                for (var i = 0, len = keys.length; i < len; ++i) {
                    var posX = parseInt(keys[i]);
                    if ((splitX - 6) <= posX && posX <= (splitX + 6)) {
                        index = _this.moveXofs[posX];
                        break;
                    }
                }
                if (index) {
                    var targetTd = _this.hideTrTdArray.eq(index);
                    var preTd = targetTd.prev();
                    var targetTdMinWidth = targetTd.data("minWidth");
                    var preTdMinWidth = preTd.data("minWidth");
                    var minLeft = preTd.position().left + preTdMinWidth;
                    var dragParams = {
                        minLeft: minLeft,
                        preTdMinWidth: preTdMinWidth,
                        targetTdMinWidth: targetTdMinWidth,
                        targetTd: targetTd,
                        preTd: preTd
                    };
                    var targetLeft = targetTd.position().left;
                    if (!_this.splitMovingLine) {
                        _this.splitMovingLine = $("<div style='position:absolute;top:0;'  class='k_datagrid_moving_line'></div>").appendTo(_this.$scrollWrap);
                        _this.splitMovingLine.draggable({
                            axis: 'h',
                            cursor: 'w-resize',
                            onStartDrag: function (e) { //开始拖动
                                var state = e.state;
                                var _data = state._data;
                                var dragParams = state.movingTarget.data("dragParams");
                                _data.dragParams = dragParams;
                                _this.isDragResize = true;
                            },
                            onDrag: function (e) {
                                var _data = e.state._data;
                                var leftOffset = _data.leftOffset;
                                if (leftOffset < 0) {
                                    if (_data.left < _data.dragParams.minLeft) {
                                        _data.left = _data.dragParams.minLeft;
                                    }
                                }
                            },
                            onStopDrag: function (e) { //拖动结束
                                var state = e.state;
                                var _data = state._data;
                                var leftOffset = _data.leftOffset;
                                var dragParams = _data.dragParams;
                                var leftTd = dragParams.preTd;
                                var rightTd = dragParams.targetTd;
                                var leftWidth = leftTd.outerWidth();
                                var rightWidth = rightTd.outerWidth();
                                if (leftOffset < 0) {
                                    leftWidth = leftWidth + leftOffset;
                                    rightWidth = rightWidth - leftOffset;
                                    if (leftWidth < dragParams.preTdMinWidth) {
                                        leftWidth = dragParams.preTdMinWidth;
                                        rightWidth = rightWidth + leftWidth - preTdMinWidth;
                                    }
                                    leftTd.outerWidth(leftWidth);
                                    rightTd.outerWidth(rightWidth);
                                } else {
                                    leftWidth = leftWidth + leftOffset;
                                    rightWidth = rightWidth - leftOffset;
                                    if (rightWidth >= dragParams.targetTdMinWidth) {
                                        leftTd.outerWidth(leftWidth);
                                        rightTd.outerWidth(rightWidth);
                                    } else { }
                                }
                                _data.dragParams = undefined;
                                _this._onResize();
                                _this.splitMovingLine.hide();
                                _this.isDragResize = false;
                            },
                            onMouseUp: function (args) {
                                _this.splitMovingLine.hide();
                            }
                        });
                    }
                    _this.splitMovingLine.css("left", targetLeft - scrollLeft).show().trigger("mousedown.draggable", {
                        pageX: e.pageX,
                        pageY: e.pageY,
                        which: e.which
                    }).data("dragParams", dragParams);
                }
            }
        },
        click: function (e) {
            var $t = $(this);
            var _this = $t.data("_this");
            if (!_this.isDragResize) {
                clearTimeout(_this.clickTimer);
                _this.clickTimer = setTimeout(function () {
                    if (typeof _this.opts.onClickCell === "function") {
                        _this.opts.onClickCell.call($t, $t.attr("filed"), $t.children("div").text());
                    }
                }, 200);
            }
        }
    };

    function _createToolbar() {
        var _this = this;
        if (!this.$toolwrap) {
            this.$toolwrap = [];
            this.$toolwrap.push($("<div class='k_datagrid_toolbar_wrap k_box_size'></div>").prependTo(this.jqObj));
        }
        for (var i = 0, l = this.$toolwrap.length; i < l; ++i) {
            this.$toolwrap[i].children().remove();
            if (this.opts.toolbar.length > 0) {
                var _opts = {
                    style: _this.opts.btnStyle, // plain / min  / normal /  big
                    showText: true,
                    methodsObject: _this.opts.methodsObject,
                    buttons: this.opts.toolbar
                };
                if ($B.config.toolbarOpts) {
                    $.extend(_opts, $B.config.toolbarOpts);
                }
                new $B.Toolbar(this.$toolwrap[i], _opts);
            } else {
                this.$toolwrap[i].hide();
            }
        }
    }

    function _sortClick(e) {
        var t = $(this);
        var $t = t.children();
        var opt = t.parent().data("opt");
        var sort;
        if ($t.hasClass('fa-down')) {
            $t.removeClass('fa-down').addClass("fa-up");
            sort = "desc";
        } else {
            $t.removeClass('fa-up').addClass("fa-down");
            sort = "asc";
        }
        var _this = e.data.ins;
        if (_this.opts.url !== '') {
            var sortField = "_col_sort_" + opt.field;
            var prs = $.extend({ pageSize: _this.pageSize }, _this.lastParams);
            prs[sortField] = sort;
            prs.page = 1;
            _load.call(e.data.ins, function () {
                _makeBody.call(e.data.ins);
            }, prs);
        }
        return false;
    }

    function _showSort() {
        $(this).children(".k_datagrid_cell_sort").width(12).slideDown(100);
    }

    function _hideSort(e) {
        $(this).children(".k_datagrid_cell_sort").slideUp(100);
    }
    /***复选事件
     *  fa-check-empty  fa-check fa-ok-squared
     * ***/
    function _checkEvent(e) {
        var $t = $(this);
        var $tr = $t.parent().parent();
        var $icon = $t.children("i");
        if ($t.hasClass("k_datagrid_chkbox_disabled")) {
            return false;
        }
        var isCheck = false;
        var setCls;
        if ($icon.hasClass("fa-check-empty")) {
            setCls = "fa-check";
            $icon.removeClass("fa-check-empty fa-ok-squared").addClass(setCls);
            isCheck = true;
        } else {
            setCls = "fa-check-empty";
            $icon.removeClass("fa-check fa-ok-squared").addClass(setCls);
        }
        var flag = $t.data("flag");
        var _this = $t.data("_this");
        var tbody = _this.$table.children("tbody");
        var trArray = tbody.children();
        var datas = [];
        if (flag) {
            trArray.each(function () {
                var $tr = $(this).data("isCheck", isCheck);
                var box = $tr.children().first().children("div");
                if (!box.hasClass("k_datagrid_chkbox_disabled")) {
                    var $i = box.children("i");
                    if (isCheck) {
                        $i.removeClass("fa-check-empty fa-ok-squared").addClass(setCls);
                    } else {
                        $i.removeClass("fa-check fa-ok-squared").addClass(setCls);
                    }
                    datas.push($.extend(true, {}, $tr.data("data")));
                }
            });
        } else {
            $tr.data("isCheck", isCheck);
            datas.push($.extend(true, {}, $tr.data("data")));
            if (_this.opts.isTree) {
                var deep = $tr.data("treeDeep");
                if ($tr.data("isparent")) {
                    var nextTr = $tr.next();
                    while (nextTr.length > 0 && nextTr.data("treeDeep") > deep) {
                        datas.push($.extend(true, {}, $tr.data("data")));
                        nextTr.data("isCheck", isCheck);
                        nextTr.children().first().children().children().removeClass("fa-check-empty  fa-check fa-ok-squared").addClass(setCls);
                        nextTr = nextTr.next();
                    }
                } else { }
            }
            var len = trArray.length;
            var chkCount = 0;
            trArray.each(function () {
                if ($(this).data("isCheck")) {
                    chkCount++;
                }
            });
            var parentChkCls;
            if (chkCount === 0) {
                parentChkCls = "fa-check-empty";
            } else if (chkCount !== len) {
                parentChkCls = "fa-ok-squared";
            } else {
                parentChkCls = "fa-check";
            }
            var headerIcon = _this.$header.children().children().last().children().first().children("div").children("i");
            headerIcon.removeClass("fa-check-empty  fa-check fa-ok-squared").addClass(parentChkCls);
        }
        if (typeof _this.opts.onCheck === "function") {
            setTimeout(function () {
                _this.opts.onCheck(isCheck, datas);
            }, 10);
        }
    }
    function _getMoveXofs(startTd, _this) {
        var moveXofs = {};
        var scrollLeft = _this.scrollLeft;
        while (startTd.length > 0) {
            var ofs = parseInt(startTd.offset().left + scrollLeft);
            moveXofs[ofs] = startTd.data("i");
            startTd = startTd.next();
        }
        return moveXofs;
    }
    /***创建表头***/
    function _createHeader() {
        var _this = this;
        this.titleTDs = {}, //最后一行td集合对象
            this.$header = $("<table></table>");
        var $tbody = $("<tbody></tbody>").appendTo(this.$header);
        var colHtml = [],
            rowspanCol = {},
            cols = _this.opts.cols,
            delTdArr = [],
            rowspanTd = [],
            sortableTd = [],
            colIndexFix = _this.opts.checkBox ? 1 : 0, //设置titleTDs开始下标           
            lastRowIndex = cols.length - 1,
            isCheckBox = _this.opts.checkBox;
        var getColIndexFn = function (tr) {
            var colIndex = 0;
            tr.children().each(function () {
                var td = $(this),
                    colspan = td.attr("colspan");
                if (colspan) {
                    colIndex = colIndex + parseInt(colspan);
                } else {
                    colIndex = colIndex + 1;
                }
            });
            return colIndex;
        };
        /****
         * 先创建好tr td html放置于数组中，最后循环一次appendto
         * 处理colspan情况，colspan不需要处理，外部的json已经要求不能有多余的td
         * 处理rowspan情况
         * *****/
        var col, tr, lastColIndex, opt, colspan, rowspan, td, sortBtn,
            txtWrap, _tmpIdx, isUrl = _this.opts.url !== "",
            txtWrapHtml = "<div class='k_box_size k_datagrid_cell_text'></div>",
            sortHtml = "<div  class='k_datagrid_cell_sort k_box_size'><i class='k_datagrid_i_icon fa'></i></div>";
        for (var rowIdx = 0, l = cols.length; rowIdx < l; ++rowIdx) {
            col = cols[rowIdx];
            tr = $("<tr>");
            lastColIndex = 0;
            var isLastRow = rowIdx === lastRowIndex;
            if (isLastRow) {
                lastColIndex = col.length - 1; //计算记录共有多少列;
            }
            for (var j = 0, jl = col.length; j < jl; ++j) {
                opt = isLastRow ? $.extend({}, defaultColOpts, col[j]) : col[j];
                if (opt.width === "") {
                    opt.width = "auto";
                } else if (opt.width && !$.isNumeric(opt.width) && opt.width !== "auto") {
                    opt.width = parseFloat(opt.width.replace("px", ""));
                }
                colspan = opt.colspan ? 'colspan="' + opt.colspan + '"' : "";
                rowspan = opt.rowspan ? 'rowspan="' + opt.rowspan + '"' : "";
                td = $("<td " + rowspan + " " + colspan + " class='k_box_size'></td>");
                if (rowIdx === 0) {
                    td.css("border-top", "none");
                }
                if (j === 0) {
                    td.css("border-left", "none");
                }
                if (j === jl - 1) {
                    td.css("border-right", "none");
                }
                txtWrap = $(txtWrapHtml).appendTo(td);
                txtWrap.append("<div style='width:100%' class='k_datagrid_title_text k_box_size'>" + opt.title + "</div>");
                if (rowspan !== "") {
                    rowspanTd.push(td);
                }
                if (opt.sortable && isUrl) {
                    sortBtn = $(sortHtml).appendTo(td).on("click", {
                        ins: _this
                    }, _sortClick);
                    if (_this.opts.sortOrder === "desc") {
                        sortBtn.children("i").addClass("fa-down");
                    } else {
                        sortBtn.children("i").addClass("fa-up");
                    }
                    td.mouseenter(_showSort);
                    td.mouseleave(_hideSort);
                    sortableTd.push(td);
                }
                td.outerWidth(opt.width).on(tdEvents).data("_this", _this);
                /***
                 *循环已经添加到tr的td，计算当前的列索引 需要处理colspan的情况
                 ****/
                var colIndex = getColIndexFn(tr);
                //记录td归属的行、列
                td.data("index", {
                    "r": rowIdx,
                    "c": colIndex
                }).data("opt", opt);
                if (rowIdx === lastRowIndex) { //记录最后一行的td
                    var tmp = colIndexFix + j;
                    this.titleTDs[tmp] = td;
                }
                /*判断是否是被rowspan的单元格
                 *1)先将rowspan的列记录到rowspanCol,记录当前rowspan的范围
                 *2)如果该列存在rowspan，则取出然后判断当前的td是否在rowspan范围内，如果在则记录起来
                 * *****/
                var rowSpanMsg = rowspanCol[colIndex];
                if (rowSpanMsg && rowSpanMsg.span) {
                    if (rowIdx <= rowSpanMsg.rowIdx) {
                        td.hide();
                        delTdArr.push(td);
                        if (rowIdx === lastRowIndex) { //最后一行,将最后td的opt合并到rowspan的td上
                            var _opt1 = rowSpanMsg.td.data("opt");
                            var crOpt = td.data("opt");
                            var newOpt = $.extend({}, crOpt, _opt1);
                            delete newOpt.rowspan;
                            delete newOpt.colspan;
                            rowSpanMsg.td.data("opt", newOpt);
                            rowSpanMsg.td.outerWidth(newOpt.width);
                            _tmpIdx = colIndexFix + j;
                            this.titleTDs[_tmpIdx] = rowSpanMsg.td; //修正为colspan的td 
                        }
                    }
                }
                //记录rowspan的列
                if (opt.rowspan) {
                    rowspanCol[colIndex] = {
                        span: true,
                        rowIdx: rowIdx + opt.rowspan - 1,
                        td: td
                    };
                }
                tr.append(td);
            }
            colHtml.push(tr);
        }
        //删除被rowspan的td
        for (var d = 0, ll = delTdArr.length; d < ll; ++d) {
            delTdArr[d].remove();
        }
        var checkboxIcon = "<i class='fa  fa-check-empty'></i>",
            isLast, chkTd, opTd;
        //往header添加创建的tr，并在此时加入checkbox operator列
        for (var k = 0, kl = colHtml.length; k < kl; ++k) {
            isLast = k === kl - 1;
            if (isCheckBox) {
                chkTd = $("<td style='border-left:none;' class='k_box_size' ><div style='width:" + (chkbox_w - 2) + "px' class='k_box_size k_datagrid_cell_chkbox'></div></td>");
                chkTd.data("opt", {
                    width: chkbox_w
                });
                chkTd.outerWidth(chkbox_w);
                colHtml[k].prepend(chkTd);
                lastColIndex = lastColIndex + 1;
            }
            if (_this.opts.oprCol && k === 0) {
                var oprWidth = 'auto';
                if (_this.opts.oprColWidth) {
                    oprWidth = _this.opts.oprColWidth;
                }
                opTd = $("<td rowspan='" + kl + "' class='k_box_size'  style='border-right:none;'><div  class='k_box_size k_datagrid_cell_text'><div class='k_datagrid_title_text k_box_size'>" + $B.config.oprColName + "</div></div></td>");
                colHtml[k].append(opTd.outerWidth(oprWidth));
                rowspanTd.push(opTd);
                _tmpIdx = lastColIndex + 1;
                this.titleTDs[_tmpIdx] = opTd; //operator 
                opTd.data("operator", true).data("opt", {
                    width: oprWidth,
                    isOpr: true
                });
            }
            $tbody.append(colHtml[k]);
            if (isCheckBox && isLast) {
                chkTd = colHtml[k].children().first().children()
                    .append(checkboxIcon)
                    .click(_checkEvent).data("flag", true).data("_this", _this);
                this.titleTDs[0] = chkTd.parent(); //checkbox
                chkTd.data("opt", {
                    width: chkbox_w
                });
                this.titleCheckBox = chkTd.children("i");
            }
            if (_this.opts.onHeadRender) {
                _this.opts.onHeadRender.call(colHtml[k]);
            }
        }
        var wrapWidth = this.$headWrap.width();
        //第一行隐藏行
        var hideTr = $("<tr style='height:0;'/>");
        var autoTdArray = []; //隐藏行里面的auto列     
        var keys = Object.keys(this.titleTDs);
        var _css, titleTd, widthValue, tmpTd, minTableWidth = 0,
            tmpWidth, minWidth, fs, userMinWidth, tdOpt;
        for (var m = 0, klength = keys.length; m < klength; ++m) {
            _css = {
                height: 0,
                "border-top": "none",
                "border-bottom": "none"
            };
            titleTd = this.titleTDs[keys[m]];
            if (m === 0) {
                _css["border-left"] = "none";
            }
            if (m === klength - 1) {
                _css["border-right"] = "none";
            }
            tdOpt = titleTd.data("opt");
            widthValue = tdOpt.width;
            tmpTd = $("<td class='k_datagrid_header_hide_td'/>").css(_css).appendTo(hideTr).outerWidth(widthValue).data("i", m).data("opt", tdOpt);
            if (widthValue === "auto") { //需要设置最小列宽  
                fs = titleTd.find(".k_datagrid_title_text").css("font-size");
                minWidth = undefined;
                userMinWidth = tdOpt.minWidth;
                if (userMinWidth && userMinWidth !== "") {
                    if (!$.isNumeric(userMinWidth)) {
                        userMinWidth = parseInt(userMinWidth.replace("px", ""));
                    }
                    minWidth = userMinWidth;
                } else {
                    minWidth = $B.getCharWidth(tdOpt.title, fs) + 16;
                }
                minTableWidth = minTableWidth + minWidth;
                autoTdArray.push(tmpTd);
            } else {
                minWidth = $B.getCharWidth(tdOpt.title, fs) + 16;
                tmpWidth = $.isNumeric(widthValue) ? widthValue : parseFloat(widthValue.replace("px", ""));
                minTableWidth = minTableWidth + tmpWidth;
            }
            tmpTd.data("minWidth", minWidth);
            titleTd.data("minWidth", minWidth); //用于拖动改变大小
            titleTd.outerWidth("auto");
        }
        var i, len;
        if (wrapWidth < minTableWidth) {
            for (i = 0, len = autoTdArray.length; i < len; ++i) {
                autoTdArray[i].outerWidth(autoTdArray[i].data("minWidth"));
            }
        }
        this.autoTdArray = autoTdArray;
        this.minTableWidth = parseInt(minTableWidth + 1);
        hideTr.prependTo(this.$header);
        this.$header.appendTo(this.$headWrap);
        //自适应一次外层容器
        var tableWidth = this.$header.outerWidth();
        if (this.$header.width() < minTableWidth) {
            this.$header.width(minTableWidth);
        }
        var diffWidth = wrapWidth - tableWidth;
        if (diffWidth > 0) {
            this.$header.outerWidth("100%");
            for (i = 0, len = autoTdArray.length; i < len; ++i) {
                td = autoTdArray[i];
                tmpWidth = td.outerWidth();
                if (tmpWidth < td.data("minWidth")) {
                    td.outerWidth(td.data("minWidth"));
                }
            }
        }
        this.hideTrTdArray = hideTr.children();
        //记录td的实际宽度到data("outerWidth") 
        var tmpCls = ".k_datagrid_cell_text";
        this.updateColsWidthArray();
        //列宽拖动功能记录坐标
        var startTd = hideTr.children().eq(colIndexFix);
        tmpCls = ".k_datagrid_cell_sort";
        setTimeout(function () {
            _this._setColPosition();
            //修正rowspan td的排序icon的高度bug
            var h, isIE = $B.isIE();
            for (i = 0, len = sortableTd.length; i < len; ++i) {
                td = sortableTd[i];
                var $sort = td.children(tmpCls);
                if (isIE) {
                    h = td.outerHeight() - 1;
                } else {
                    h = td.height();
                }
                $sort.height(h);
            }
        }, 300);
    }
    /***树节点事件***/
    function _treeClick(e) {
        var _this = e.data._this;
        var $span = $(this);
        var tr = $span.parent().parent().parent();
        var treeDeep = tr.data("treeDeep");
        var icon = $span.children("i");
        var isClosed;
        if (icon.hasClass("fa-folder-open")) {
            icon.removeClass("fa-folder-open").addClass("fa-folder");
            isClosed = true;
        } else {
            icon.removeClass("fa-folder").addClass("fa-folder-open");
            isClosed = false;
        }
        tr.data("closed", isClosed);
        var nextTr = tr.next();
        var data = tr.data("data");
        //远程加载
        if (!isClosed && $.isArray(data.children) && data.children.length === 0) {
            var pLeft = $span.parent().css("padding-left");
            var loadingTr = $("<tr><td style='padding-left:" + pLeft + "' class='k_box_size' colspan='" + tr.children().length + "'><i class='fa fa-cog fa-spin fa-1.6x fa-fw margin-bottom'></i>" + $B.config.loading + "</td></tr>");
            var opts = _this.opts;
            loadingTr.insertAfter(tr);
            var params = $.extend({
                pid: data.data[opts.idField]
            }, _this.lastParams);
            if (typeof opts.setParams === "function") {
                $.extend(params, _this.opts.setParams());
            }
            var ajaxOpts = {
                async: true,
                url: opts.url,
                data: params,
                ok: function (message, data) {
                    if (data.length > 0) {
                        data.children = data;
                    }
                    for (var i = 0, len = data.length; i < len; ++i) {
                        _createTr.call(_this, data, tr, parseInt(treeDeep) + 1, false);
                    }
                    if (opts.onLoaded) {
                        setTimeout(function () {
                            opts.onLoaded(data);
                        }, 10);
                    }
                },
                final: function (res) {
                    var isEmpty = false;
                    if (typeof res.data !== "undefined") {
                        if (res.data.length === 0) {
                            isEmpty = true;
                        }
                    } else if ($.isArray(res) && res.length === 0) {
                        isEmpty = true;
                    }
                    if (isEmpty) {
                        loadingTr.children().html("<i style='padding-right:6px;' class='fa fa-info _no_data'></i>" + $B.config.noData);
                        setTimeout(function () {
                            loadingTr.remove();
                            icon.removeClass("fa-folder-open").addClass("fa-folder");
                        }, 1600);
                    } else {
                        loadingTr.remove();
                    }
                }
            };
            _this.ajax(ajaxOpts);
        } else {
            var deep, parentTrArray = [],
                parentStatus = {};
            parentStatus[treeDeep] = isClosed;
            while (nextTr.length > 0) {
                deep = nextTr.data("treeDeep");
                if (deep <= treeDeep) {
                    break;
                }
                if (isClosed) { //关闭则所有都要关闭
                    nextTr.hide();
                } else { //显示，并不一定都是需要显示
                    if (deep === treeDeep + 1) {
                        nextTr.show();
                    }
                    if (nextTr.data("isparent")) { //处理下级元素
                        parentTrArray.push(nextTr);
                        parentStatus[deep] = nextTr.data("closed");
                    }
                }
                nextTr = nextTr.next();
            }
            //循环处理parent show
            var $p, pStatus;
            for (var i = 0, len = parentTrArray.length; i < len; ++i) {
                $p = parentTrArray[i];
                deep = $p.data("treeDeep");
                isClosed = $p.data("closed");
                pStatus = parentStatus[deep - 1];
                if (!isClosed && !pStatus) {
                    deep = deep + 1;
                    nextTr = $p.next();
                    while (nextTr.length > 0 && nextTr.data("treeDeep") === deep) {
                        nextTr.show();
                        nextTr = nextTr.next();
                    }
                }
            }
            _this._onResize();
        }
        var selection;
        if (window.getSelection) {
            selection = window.getSelection();
        } else if (document.selection) {
            selection = document.selection.createRange();
        }
        try {
            selection.removeAllRanges();
        } catch (ex) { }
        return false;
    }
    /***创建行***/
    function _createTr(list, vBody, treeDeep, parentIsClose) {
        var _this = this;
        var isTree = this.opts.isTree;
        var titleKeys = Object.keys(this.titleTDs);
        var $tr, data, idx, _txt, $txt;
        var tempArray = [];
        var isTbody = vBody[0].nodeName === "TBODY";
        for (var j = 0, dl = list.length; j < dl; ++j) {
            $tr = $("<tr/>");
            data = list[j];
            idx = 0;
            $tr.data("data", data).data("opts", this.opts).data("treeDeep", treeDeep);
            if (_this.opts.splitColLine !== "k_datagrid_td_all_line") {
                $tr.addClass("k_datagrid_old_even_cls");
            }
            for (var p = 0, plen = titleKeys.length; p < plen; ++p) {
                var tdHeader = _this.titleTDs[p],
                    tdOpt = tdHeader.data("opt"),
                    _width = _this.colsWidthArray[p],
                    innerWidth = _width - 2;
                if (j === 0) {
                    tempArray.push(_width);
                }
                var filed = tdOpt.field ? tdOpt.field : "";
                var $td = $("<td filed='" + filed + "' class='k_box_size'></td>");
                $td.outerWidth(_width);
                if (p === 0) {
                    $td.css("border-left", "none");
                }
                if (p === plen - 1) {
                    $td.css("border-right", "none");
                }
                if (_this.opts.splitColLine) {
                    $td.addClass(_this.opts.splitColLine);
                }
                if (_this.opts.checkBox && p === 0) { //checkbox                                        
                    $('<div class="k_box_size k_datagrid_cell_text k_datagrid_cell_chkbox"><i class="fa  fa-check-empty"></i></div>').appendTo($td);
                    $txt = $td.css("text-align", "center").data("isCheckBox", true).children("div")
                        .data("data", data)
                        .data("_this", _this)
                        .data("treeDeep", treeDeep);
                    if (isTree && data.children) {
                        $txt.data("isparent", true);
                        if (_this.opts.onlyChkChild) {
                            $txt.addClass("k_datagrid_cell_chkbox_disabled");
                        }
                    }
                    $txt.click(_checkEvent).dblclick(function () {
                        return false;
                    });
                } else {
                    var txt, txtAlign = 'center',
                        isOperator = tdHeader.data("operator");
                    if (isOperator) { //operator
                        txt = '';
                        $td.css("text-align", "center");
                    } else { //data
                        if (isTree) {
                            txt = data.data[tdOpt.field];
                        } else {
                            txt = data[tdOpt.field];
                        }
                        if (tdOpt.align) {
                            txtAlign = tdOpt.align;
                        }
                        if (typeof txt === "undefined") {
                            txt = "";
                        }
                    }
                    if (tdOpt && !isOperator) {
                        _txt = undefined;
                        if (typeof tdOpt.formatter === "function") {
                            _txt = tdOpt.formatter(txt, data, tdOpt.field);
                        } else if (typeof window[tdOpt.formatter] === "function") {
                            _txt = window[tdOpt.formatter](txt, data, tdOpt.field);
                        }
                        if (_txt) {
                            txt = _txt;
                        }
                    }
                    $txt = $('<div style="text-align:' + txtAlign + ';" class="k_box_size k_datagrid_cell_text">' + txt + '</div>').appendTo($td);
                    $txt.appendTo($td);
                    $td.data("txt", $txt.text());
                    if (isTree) { //如果是树形  k_datagrid_cell_text_nowrap                    	
                        var isFirstTd = (_this.opts.checkBox && p === 1) || (!_this.opts.checkBox && p === 0);
                        if (isFirstTd) {
                            var _treeDeep = treeDeep,
                                _padding = 0;
                            while (_treeDeep > 0) {
                                _padding = _padding + 20;
                                _treeDeep--;
                            }
                            if (_padding === 0) {
                                _padding = 2;
                            }
                            $txt.css({
                                "text-align": "left",
                                "padding-left": _padding
                            });
                            var $i;
                            if (data.children) {
                                var icon_cls = 'fa-folder';
                                var isClosed = true;
                                if (data.children.length > 0 && !data.closed) {
                                    icon_cls = 'fa-folder-open';
                                    isClosed = false;
                                }
                                $tr.data("closed", isClosed);
                                $i = $("<span style='cursor:pointer;'><i style='padding:2px 6px 2px 2px;cursor:pointer;' class='fa " + icon_cls + "'></i></span>").prependTo($txt);
                                $i.on("click", {
                                    _this: _this
                                }, _treeClick).dblclick(function () {
                                    return false;
                                });
                                $i = $i.children();
                            } else {
                                $i = $("<i style='padding:2px 6px 2px 2px;' class='fa fa-doc'></i>").prependTo($txt);
                            }
                            if (_this.opts.treeIconColor) {
                                $i.css("color", _this.opts.treeIconColor);
                            }
                        }
                    }
                    if (isOperator) {
                        var _btns = data.toolbar; //兼容 tree数据
                        if (_btns) {
                            delete data.toolbar;
                            _this.rowToolbars.push(new $B.Toolbar($txt, {
                                context: $tr, //点击事件的上下文
                                params: data, //用于集成到tree datagrid时 行按钮的数据参数
                                align: 'center', //对齐方式，默认是left 、center、right
                                style: _this.opts.btnStyle, //'plain',// plain / min  / normal /  big
                                showText: _this.opts.showBtnText, // min 类型可以设置是否显示文字
                                methodsObject: _this.opts.methodsObject, //事件集合对象
                                fontSize: '16',
                                iconColor: $B.config.rowBtnColor,
                                buttons: _btns
                            }));
                            //修正字体图标渲染延后的bug
                            $td.data("isOpr", true);
                            $td.data("oprCount", _btns.length);
                        }
                    } else {
                        $td.on(tdEvents).data("opts", _this.opts).data("field", tdOpt.field).data("_this", _this);
                    }
                }
                $td.children(".k_datagrid_cell_text").outerWidth(innerWidth);
                $tr.append($td);
                idx = idx + 1;
            }
            if (isTbody) {
                vBody.append($tr);
            } else {
                $tr.insertAfter(vBody);
            }
            $tr.on(trEvents).data("_this", _this);
            if (_this.opts.onRowRender) {
                _this.opts.onRowRender.call($tr, data, j);
            }
            if (isTree) {
                if (parentIsClose) {
                    $tr.hide();
                }
                if (data.children) {
                    var _len = data.children.length;
                    $tr.data("isparent", true).data("childrens", _len).data("checked", 0);
                    if (_len > 0) {
                        if (typeof parentIsClose !== "undefined" && parentIsClose) {
                            data.closed = parentIsClose;
                        }
                        if (isTbody) {
                            _createTr.call(this, data.children, vBody, treeDeep + 1, data.closed);
                        } else {
                            _createTr.call(this, data.children, $tr, treeDeep + 1, data.closed);
                        }
                    }
                }
            }
        }
    }

    function _makeBody() {
        var _this = this,
            topPgPostion = "right",
            display,
            list,
            treeDeep = 0;
        if (this.opts.isTree) {
            list = this.opts.data;
        } else {
            list = this.opts.data.resultList;
        }
        for (var k = 0, klen = this.rowToolbars.length; k < klen; ++k) {
            this.rowToolbars[k].destroy();
        }
        _this.rowToolbars = [];
        if (!this.$toolwrap) {
            this.$toolwrap = [];
            display = _this.showToolbar ? 'block' : 'none';
            if (this.$title) {
                var tmp = $("<div style='display:" + display + "' class='k_datagrid_toolbar_wrap k_box_size clearfix'></div>").insertAfter(this.$title);
                this.$toolwrap.push(tmp);
            } else {
                this.$toolwrap.push($("<div  style='display:" + display + "'  class='k_datagrid_toolbar_wrap k_box_size clearfix'></div>").prependTo(this.jqObj));
            }
        }
        if (!this.opts.isTree) {
            for (var l = 0, ll = _this.pgList.length; l < ll; ++l) {
                _this.pgList[l].clear();
            }
            _this.pgList = [];
            var pgOpts = {
                height: 25,
                page: this.opts.data.currentPage,
                total: this.opts.data.totalSize, //总数量
                pageSize: this.opts.pageSize, //页大小
                buttons: this.opts.pgBtnNum ? this.opts.pgBtnNum : 10, //页按钮数量
                startpg: this.opts.startPage,
                position: topPgPostion,
                summary: true,
                onClick: function (p, ps, startpg) {
                    _this.opts.startPage = startpg;
                    _this.opts.page = p;
                    _this.opts.pageSize = ps;
                    _this.pageSize = ps;
                    var prs = $.extend(_this.currentParams, {
                        page: p,
                        pageSize: ps
                    });
                    _load.call(_this, function () {
                        _makeBody.call(_this);
                    }, prs);
                }
            };
            //创建分页工具栏  "currentPage":1,"totalSize":2
            if (this.opts.pgposition === "both" || this.opts.pgposition === "top") {
                var $pgTool = this.$toolwrap[0].children("k_datagrid_pagination_top_wrap");
                if ($pgTool.length === 0) {
                    $pgTool = $("<div class='k_datagrid_pagination_top_wrap' style='float:" + topPgPostion + "'></div>").appendTo(this.$toolwrap[0]);
                }
                _this.pgList.push(new $B.Pagination($pgTool, pgOpts));
            }
            if (this.opts.pgposition === "both" || this.opts.pgposition === "bottom") {
                if (this.$toolwrap.length === 1) {
                    var tmpCls = "";
                    if (_this.opts.fillParent) {
                        tmpCls = "k_datagrid_tool_tottom_border";
                    }
                    this.$toolwrap.push($("<div class='k_datagrid_toolbar_wrap k_box_size " + tmpCls + "'></div>").appendTo(this.jqObj));
                }
                pgOpts.position = "left";
                _this.pgList.push(new $B.Pagination(this.$toolwrap[1], pgOpts));
            }
        }
        /****
         * 循环列表---》循环标题行----》创建tr td
         * _autoTDS将auto列的td记录起来
         * ******/
        if (list.length > 0) {
            this.$table.children("tbody").remove();
            var vBody = $("<tbody/>");
            this.updateColsWidthArray();
            _createTr.call(this, list, vBody, treeDeep);
            vBody.children().first().children().each(function () {
                $(this).css("border-top", "none");
            });
            this.$table.append(vBody);
            _this._onResize();
        }
    }

    function _load(fn, params) {
        var _this = this;
        var opts = this.opts;
        if (opts.url === "") {
            return;
        }
        if (this.titleCheckBox) {
            this.titleCheckBox.removeClass("fa-check fa-ok-squared").addClass("fa-check-empty");
        }
        if (typeof opts.setParams === "function") {
            $.extend(params, this.opts.setParams());
        }
        var mainWrap = this.$bodyWrap.parent().parent();
        if (!this.$mask) {
            var loadingTip = $B.config.loading;
            var w = $B.getCharWidth(loadingTip) + 20;
            var loadingHtml = "<div style='width:" + w + "px;z-index:2147483647;' class='k_datagrid_loading'><i class='fa fa-cog fa-spin fa-1.6x fa-fw margin-bottom'></i>" + loadingTip + "</div>";
            this.$mask = $("<div class='k_datagrid_load_mask'><div style='display:block;' class='k_model_mask'></div>" + loadingHtml + "</div>").appendTo(mainWrap);
        }
        var Headerheight = 0;
        this.$scrollWrap.prevAll().each(function () {
            Headerheight = Headerheight + $(this).outerHeight();
        });
        Headerheight = Headerheight + this.$headWrap.outerHeight();
        var bodyHeight = this.$bodyWrap.height();
        var fixPadding = false;
        if (bodyHeight === 0) {
            this.$bodyWrap.css("padding-bottom", 40);
            fixPadding = true;
        }
        this.$mask.children(".k_datagrid_loading").css("margin-top", Headerheight + 10);
        this.$mask.show().fadeIn(100);
        _this.lastParams = params;
        //补充上排序字段
        if (this.opts.sortField) {
            var fieldKeys = Object.keys(this.opts.sortField),
                field;
            for (var j = 0, jlen = fieldKeys.length; j < jlen; ++j) {
                field = fieldKeys[j];
                var sortKey = "_col_sort_" + field;
                if (!params[field] && !params[sortKey]) {
                    params[sortKey] = this.opts.sortField[field];
                }
            }
        }
        var ajaxOpts = {
            async: true,
            url: opts.url,
            data: params,
            ok: function (message, data) {
                _this.opts.data = data;
                _this.opts.data.currentPage = params.page;
                _this.opts.data.totalSize = data.totalSize; //总数量
                _this.opts.pageSize = params.pageSize; //页大小
                _makeBody.call(_this);
                if (opts.onLoaded) {
                    setTimeout(function () {
                        opts.onLoaded(data);
                    }, 10);
                }
                if ($B.isIE()) {
                    _this._fixIE();
                }
            },
            final: function (res) {
                var isEmpty = false;
                if (typeof res.data !== "undefined") {
                    if ((_this.opts.isTree && res.data.length === 0) || !res.data.totalSize) {
                        isEmpty = true;
                    }
                } else if ((_this.opts.isTree && $.isArray(res) && res.length === 0) || !res.totalSize) {
                    isEmpty = true;
                }
                if (isEmpty) {
                    _this.$table.children("tbody").remove();
                    var w = _this.$bodyWrap.width() - 2;
                    var emptyTr = $("<tbody><tr><td style='text-align:center;width:" + w + "px' class='k_box_size' colspan='" + _this.$header.children().children().first().children().length + "'><i style='padding-right:6px;' class='fa fa-info  _no_data'></i>" + $B.config.noData + "</td></tr></tbody>");
                    _this.$table.append(emptyTr);
                }
                if (fixPadding) {
                    _this.$bodyWrap.css("padding-bottom", 0);
                }
                _this.$mask.fadeOut(200, function () {
                    _this.$mask.hide();
                });
            }
        };
        this.ajax(ajaxOpts);
    }
    /**
     * 构造函数
     * **/
    function Datagrid(target, opts) {      
        $B.extend(this, Datagrid); //继承父类
        this.opts = $.extend({}, defaultOpts, opts);
        if (!$.isArray(this.opts.cols[0])) {
            this.opts.cols = [this.opts.cols];
        }
        if (!scrollWidth) {
            scrollWidth = $B.getScrollWidth();
        }
        this["tdTip"] = _getBody().children("#k_datagrid_td_tip");
        if (this["tdTip"].length === 0) {
            this["tdTip"] = $("<div id='k_datagrid_td_tip' style='width:auto;min-width:150px;display:none;top:-1000px;' class=' k_box_shadow'><p></p></div>").appendTo(_getBody());
        }
        this.showToolbar = (!$.isArray(this.opts.toolbar) || this.opts.toolbar.length === 0) ? false : true;
        if (!this.showToolbar) {
            this.showToolbar = this.opts.pgposition === "top" || this.opts.pgposition === "both";
        }
        this.page = this.opts.page;
        this.pageSize = this.opts.pageSize;
        target.addClass("k_datagrid_table_body");
        this.jqObj = $('<div class="k_datagrid_main_wrap k_box_size"><div class="k_datagrid_scroll_wrap k_box_size"><div class="k_datagrid_head_wrap k_box_size"></div><div class="k_datagrid_body_wrap k_box_size">' + target[0].outerHTML + '</div></div></div>');
        this.$bodyWrap = this.jqObj.find(".k_datagrid_body_wrap");
        this.$scrollWrap = this.jqObj.find(".k_datagrid_scroll_wrap");
        this.$headWrap = this.jqObj.find(".k_datagrid_head_wrap");
        this.$table = this.$bodyWrap.find("table");
        this.jqObj.insertAfter(target);
        target.remove();
        this.pgList = [];
        this.rowToolbars = [];
        this.$bodyWrap.addClass("k_datagrid_body_border_fix");
        var _this = this;
        if ($.isArray(this.opts.toolbar) && this.opts.toolbar.length > 0) {
            _createToolbar.call(this);
        }
        if (this.opts.title && this.opts.title !== '') {
            this.$title = $("<div class='k_datagrid_head_title k_box_size'></div>").prependTo(this.jqObj);
            this.$title.append("<h6>" + this.opts.title + "</h6>").appendTo(this.$title);
            if (this.opts.iconCls !== '') {
                this.$title.children().prepend('<i class="fa ' + this.opts.iconCls + '"></i>&nbsp');
            }
        }
        var isExist = false;
        if (this.opts.url !== "") {
            for (var i = 0, l = this.opts.pageList.length; i < l; ++i) {
                if (this.opts.pageList[i] === this.opts.pageSize) {
                    isExist = true;
                    break;
                }
            }
            if (!isExist) {
                this.opts.pageList.push(this.opts.pageSize);
            }
        }
        _createHeader.call(this);
        _this._fillParent();
        //优先本地数据
        if (this.opts.data !== null) {
            setTimeout(function () {
                _makeBody.call(_this);
            }, 0);
        } else if (this.opts.url !== '' && this.opts.loadImd) {
            var params = {
                page: 1,
                pageSize: this.opts.pageSize
            };
            _load.call(_this, function () {
                _makeBody.call(_this);
            }, params);
        }
        if (!this.showToolbar && this.opts.title === "") {
            this.jqObj.css("border-top", "none");
        }
        var delayFixTimer;
        var nsId = $B.getUUID();
        $(window).on("resize."+nsId,function () {
            if(_this._onResize){
                _this._onResize();
                clearTimeout(delayFixTimer);
                delayFixTimer = setTimeout(function () {
                    _this._onResize();
                }, 200);
            }else{
                $(this).off("."+nsId);
            }            
        });
        this.scrollLeft = 0;
        var scrollfn = function () {
            _this._hideToolBtnList();
            var left = $(this).scrollLeft();
            _this.$header.css("left", -left);
            _this.scrollLeft = left;
        };
        this.$bodyWrap.on("scroll", scrollfn);
    }
    Datagrid.prototype = {
        _fixIE: function () {
            if (!this.hasFixIe) {
                this.hasFixIe = true;
                if (this.hideTrTdArray.length > 1) {
                    var targetTd = this.hideTrTdArray.eq(1);
                    var prevTd = this.hideTrTdArray.eq(0);
                    prevTd.outerWidth(prevTd.outerWidth() + 1);
                    targetTd.outerWidth(targetTd.outerWidth() - 1);
                    this._onResize();
                }
            }
        },
        _hideToolBtnList: function () {
            if (this.opts.oprCol) {
                _getBody().children("#k_toolbar_drop_wrap").hide();
            }
        },
        _fillParent: function () {
            if (this.opts.fillParent) { //垂直方向沾满父空间
                var parentHeight = this.jqObj.parent().height();
                var siblingsHeight = this.$headWrap.outerHeight();
                if (this.opts.pgposition === "bottom" || this.opts.pgposition === "both") {
                    siblingsHeight = siblingsHeight + 40;
                }
                this.$scrollWrap.siblings().each(function () {
                    var $t = $(this);
                    if (!$t.hasClass("k_datagrid_load_mask")) {
                        siblingsHeight = siblingsHeight + $t.outerHeight();
                    }
                });
                var bodyFixedHeight = parentHeight - siblingsHeight;
                this.$bodyWrap.outerHeight(bodyFixedHeight).css({
                    "overflow-y": "auto"
                });
            }
        },
        _setColPosition: function () {
            var startTd = this.hideTrTdArray.first().next();
            if (this.opts.checkBox) {
                startTd = startTd.next();
            }
            var moveXofs = _getMoveXofs(startTd, this);
            this.moveXofs = moveXofs;
        },
        updateColsWidthArray: function () {
            var widthArray = [];
            var keys = Object.keys(this.titleTDs);
            for (var i = 0, len = keys.length; i < len; ++i) {
                widthArray.push(this.titleTDs[keys[i]].outerWidth());
            }
            this.colsWidthArray = widthArray;
            return this.colsWidthArray;
        },
        /**大小变化适配**/
        _onResize: function () {           
            var _this = this;
            //检测是否出现了横向滚动条
            var isScroll = false;
            if (this.$table.outerHeight() > this.$bodyWrap.height()) {
                isScroll = true;
            }
            var headerWidth = this.$header.parent().width();
            var isFixWidth = this.$header.data("isFixWidth");
            var td, i, len, mWidth;
            if (isFixWidth) {
                if (headerWidth > this.minTableWidth) {
                    this.$header.removeData("isFixWidth");
                    for (i = 0, len = this.autoTdArray.length; i < len; ++i) {
                        td = this.autoTdArray[i];
                        td.css("width", "auto");
                    }
                }
            } else {
                if (headerWidth < this.minTableWidth) {
                    this.$header.data("isFixWidth", true);
                    for (i = 0, len = this.autoTdArray.length; i < len; ++i) {
                        td = this.autoTdArray[i];
                        mWidth = td.data("minWidth");
                        td.css("width", mWidth);
                    }
                }
            }
            this.updateColsWidthArray();
            this.$table.children("tbody").children().each(function () {
                var tdArray = $(this).children();
                var len = tdArray.length;
                if(len === 1){
                   if( tdArray.find("._no_data").length > 0){
                       return true;
                   }
                }
                tdArray.each(function (i) {
                    var w = _this.colsWidthArray[i];
                    if (isScroll && i === len - 1) {
                        w = w - scrollWidth;
                    }
                    var _td = $(this).outerWidth(w);
                    _td.children().outerWidth(w - 2);
                });
            });
            clearTimeout(this._setColPositionTimer);
            this._setColPositionTimer = setTimeout(function () {
                _this._setColPosition();
                _this._hideToolBtnList();
            }, 100);
        },
        getData: function () {
            return this.opts.data;
        },
        /**
         * 打开内嵌页面
         args={
         	content:内容或者url
          	type:如果是url请求的时候，type=html/iframe,
          	onLoaded:fn() 如果是url加载，会触发加载完成事件
         }
         * **/
        openInner: function (tr, args) {
            if (tr.next().hasClass("tr_inner")) {
                return;
            }
            if (this.innerTr) {
                this.innerTr.remove();
            }
            var _this = this;
            var len = tr.children().length;
            var $tr = $("<tr class='tr_inner'><td colspan='" + len + "' style='position:relative;'><div class='tr_inner_content'></div></td></tr>").insertAfter(tr);
            var $td = $tr.children();
            var $content = $td.children();
            $("<a style='position:absolute;top:0;right:0;cursor: pointer;' title='" + $B.config.closeLable + "'><i class='fa fa-cancel-2'></i></a>").appendTo($td).click(function () {
                $tr.remove();
                _this.innerTr = undefined;
            });
            this.innerTr = $tr;
            if (args.type === 'html') {
                $B.htmlLoad({
                    target: $content,
                    url: args.content,
                    loaded: function () {
                        if (typeof args.onLoaded === 'function') {
                            args.onLoaded.call($content);
                        }
                    }
                });
            } else if (args.type === 'iframe') {
                var loading = $("<div style='padding-left:16px;'><i class='fa fa-cog fa-spin fa-1.6x fa-fw margin-bottom'></i>" + $B.config.loading + "</div>").appendTo($content);
                var iframe = $("<iframe  frameborder='0' style='overflow:visible' scrolling='auto' width='100%' height='100%' src='' ></iframe>").appendTo($content.css('overflow', 'hidden'));
                var ifr = iframe[0];
                iframe.on("load", function () {
                    loading.remove();
                    if (typeof args.onLoaded === 'function') {
                        args.onLoaded.call($content);
                    }
                });
                ifr.src = args.content;
            } else {
                $content.html(args.content);
            }
        },
        /**
         * 重新加载
         * args={} 查询参数
         * ****/
        reload: function (args) {
            var _this = this;
            _this.lastParams = {};
            var params = $.extend(true, {
                page: 1,
                pageSize: this.opts.pageSize
            }, args);
            _load.call(_this, function () {
                _makeBody.call(_this);
            }, params);
        },
        /**
         * 采用上一次查询的参数刷新当前页
         * **/
        refresh: function () {
            var _this = this;
            _load.call(_this, function () {
                _makeBody.call(_this);
            }, $.extend({
                page: 1,
                pageSize: this.opts.pageSize
            }, _this.lastParams));
        },
        /*****
         **获取选择的数据  
         ********/
        getCheckedData: function (isAll) {
            var res = [];
            this.$table.children("tbody").children().each(function () {
                var $tr = $(this);
                if ($tr.data("isCheck") || isAll) {
                    var d = $.extend(true, {}, $tr.data("data"));
                    delete d.children;
                    delete d.toolbar;
                    res.push(d);
                }
            });
            return res;
        },
        /*****
         **获取选择的数据id集合	
         *split 分隔符
         ********/
        getCheckedId: function (split) {
            var res = [];
            var _this = this;
            this.$table.children("tbody").children().each(function () {
                var $tr = $(this);
                if ($tr.data("isCheck")) {
                    var d;
                    if (_this.opts.isTree) {
                        d = $tr.data("data").data[_this.opts.idField];
                    } else {
                        d = $tr.data("data")[_this.opts.idField];
                    }
                    res.push(d);
                }
            });
            return split ? res.join(";") : res;
        },
        getRowCount: function () {
            return this.$table.children("tbody").children().length;
        }
    };
    $B["Datagrid"] = Datagrid;
    return Datagrid;
}));(function (global, factory) {
    if (typeof define === 'function' && define.amd) {
        define(['$B'], function (_$B) {
           return factory(global, _$B);
        });
    } else {
        if(!global["$B"]){
            global["$B"] = {};
        }
        factory(global, global["$B"]);
    }
}(typeof window !== "undefined" ? window : this, function (window, $B) {//
    var iframeHtml = "<iframe  class='panel_content_ifr' frameborder='0' style='overflow:visible;display:block;vertical-align:top;' scroll='none'  width='100%' height='100%' src='' ></iframe>";
    var loadingHtml = "<div class='k_box_size' style='position:absolute;z-index:2147483600;width:100%;height:26px;top:2px;left:0;' class='loading'><div class='k_box_size' style='filter: alpha(opacity=50);-moz-opacity: 0.5;-khtml-opacity: 0.5;opacity: 0.5;position:absolute;top:0;left:0;width:100%;height:100%;z-index:2147483600;background:#03369B;'></div><div class='k_box_size' style='width:100%;height:100%;line-height:26px;padding-left:16px;position:absolute;width:100%;height:100%;z-index:2147483611;color:#fff;text-align:center;'><i style='color:#fff;font-size:16px;' class='fa animate-spin fa-spin6'></i><span style='padding-left:5px;font-weight:bold;color:#fff;'>" + $B.config.loading + "</span></div></div>";
 
    /**加载数据**/
    function _load(onLoaded) {
        var _this = this;
        var opt = this.data("data");
        var isFun = typeof onLoaded === 'function';
        _this.children().remove();
        var loading;
        var scrollWrap = this;
        loading = $(loadingHtml).appendTo(_this);
        if (opt.dataType === "html") {         
            $B.htmlLoad({
                target: _this,
                url: opt.url,
                onLoaded: function () {
                    loading.fadeOut(function(){
                        $(this).remove();
                    });
                    if (isFun) {
                        onLoaded.call(_this, opt.title);
                    }
                    $B.bindTextClear(_this);
                }
            });
        } else if (opt.dataType === "json") {           
            $B.request({
                dataType: 'json',
                url: opt.url,
                ok: function (message, data) {
                    if (isFun) {
                        onLoaded.call(_this, opt.title, data);
                    }
                },
                final: function (res) {
                    loading.fadeOut(function(){
                        $(this).remove();
                    });
                }
            });
        } else {            
            var iframe = $(iframeHtml);
            var ifr = iframe[0];
            iframe.on("load",function(){
                loading.fadeOut(function(){
                    $(this).remove();
                });
                if (isFun) {
                    onLoaded.call(_this, opt.title);
                }
            });
            
            ifr.src = opt.url;
            iframe.appendTo(_this);
        }
        //绑定scroll
        // if (!scrollWrap.data("isscroll")) {
        //     $B.scrollbar(scrollWrap);
        //     scrollWrap.data("isscroll", true);
        // }
    }

    function Labeltab(jqObj, opts) {
        $B.extend(this, Labeltab);
        this.jqObj = jqObj.addClass("k_labeltab_main");
        this.opts = opts;
        this.wrap = $("<div class='k_labeltab_wrap k_box_size'></div>").appendTo(this.jqObj);
        this.title = $("<div class='k_labeltab_title k_box_size'></div>").appendTo(this.wrap);
        var _h = this.title.outerHeight();
        this.body = $("<div class='k_labeltab_body k_box_size'></div>").appendTo(this.wrap).css("border-top", _h + "px solid #fff");
        var defaultIt = null,
            limit = opts.tabs.length - 1,
            _this = this;
        this.activedItem = null;
        var _click = function () {
            var $this = $(this);
            var left = (($this.width() - 11) / 2) + $this.position().left + 5;
            var idx = parseInt($this.attr("i"));
            var it = _this.body.children(".k_labeltab_body_item").eq(idx);
            if (_this.activedItem !== null) {
                _this.activedItem.hide();
            }
            _this.activedItem = it.show();
            _this.$actived.animate({
                left: left
            }, 220, function () {
                if (_this.activedItem.children().length === 0) {
                    if (typeof _this.activedItem.data("data").dataType !== 'undefined') {
                        _load.call(_this.activedItem, _this.opts.onLoaded);
                    }
                }
            });
            if (opts.onclick) {
                var title = $this.attr("_title");
                setTimeout(function () {
                    opts.onclick.call($this,title);
                },10);
            }
        };
        for (var i = 0, len = opts.tabs.length; i < len; i++) {
            var opt = opts.tabs[i];
            var title = opt.title;
            var html = "<a i='" + i + "' _title='" + title + "'>" + title + "</a>";
            var $it = $(html).appendTo(this.title).click(_click);

            if (i < limit) {
                this.title.append("|");
            }
            var itBody = $("<div class='k_labeltab_body_item'></div>").appendTo(this.body);
            if (opt.actived || i === 0) {
                defaultIt = $it;
            }
            if (opt.url && opt.url !== "") {
                itBody.data("data", {
                    url: opt.url,
                    dataType: opt.dataType,
                    title: opt.title
                });
            } else {
                $B.scrollbar(itBody);
                itBody.append(opt.content);
            }
            if (opt.iconCls && opt.iconCls !== '') {
                $it.addClass("btn").prepend("<i class='fa " + opt.iconCls + "'></i>&nbsp");
            }
        }
        this.$actived = $('<div style="height: 6px; left:0px;" class="actived"></div>').appendTo(this.title);
        if (defaultIt !== null) {
            defaultIt.trigger('click');
        }
    }
    $B["Labeltab"] = Labeltab;
    return Labeltab;
}));(function (global, factory) {
    if (typeof define === 'function' && define.amd) {
        define(['$B', 'panel'], function (_$B) {
            return factory(global, _$B);
        });
    } else {
        if(!global["$B"]){
            global["$B"] = {};
        }
        factory(global, global["$B"]);
    }
}(typeof window !== "undefined" ? window : this, function (window, $B) {
    var Layout = function (jqObj, opts) {
        $B.extend(this, Layout); //继承父类
        this.jqObj = jqObj.addClass("k_box_size k_layout_main");
        this.opts = opts;
        this.panels = [];
        var _this = this;
        var panelOpt = {
            title: '', //标题
            iconCls: null, //图标cls，对应icon.css里的class
            toolbar: null, //工具栏对象
            width: 'auto',
            height: '100%',
            shadow: false, //是否需要阴影
            radius: false, //是否圆角
            header: true, //是否显示头部
            content: null, //静态内容或者url地址
            dataType: 'html', //当为url请求时，html/json/iframe
            closeable: false, //是否关闭
            expandable: false, //可左右收缩
            onLoaded: null, //function () { },//加载后
            onExpanded: null // function (pr) { },//左右收缩后
        };
        var widtdSet = this.anylisLayoutSize();
        var onCreated = function () {
            if (this.data("i") > 0) {
                this.css("border-left", "none");
            }
            if(typeof _this.opts.onCreated === "function"){
                _this.opts.onCreated.call(this,{i:this.data("i"),title:this.data("title")});
            }
        };
        var onExpanded = function () {
            _this.resize();
        };
        var loadFn = this.opts.onLoaded;
        var onLoaded = function(data){
            if(typeof loadFn === "function"){
                var $p = this.parent();
                loadFn.call(this,data,{i:$p.data("i"),title:$p.data("title")});
            }
        };
        for (var i = 0, len = this.opts.items.length; i < len; ++i) {
            var _popts = $.extend({}, panelOpt, this.opts.items[i]);
            var $it = $("<div class='k_layout_item k_box_size'></div>").appendTo(this.jqObj).data("width", _popts.width);
            _popts.width = widtdSet[i];
            _popts.draggable = false;
            $it.data("i", i);
            $it.data("title",_popts.title);
            _popts.onCreated = onCreated;
            _popts.onExpanded = onExpanded;
            _popts.onLoaded = onLoaded;
            var panel = new $B.Panel($it, _popts);
            this.panels.push(panel);
        }
        var nsId = $B.getUUID();
        $(window).on("resize."+nsId,$B.delayFun(function () {
            if( _this.resize){
                _this.resize();
            }else{
                $(this).off("."+nsId);
            }            
        }, 10));
    };
    Layout.prototype = {
        constructor: Layout,
        anylisLayoutSize: function () {
            var tmp = {},
                _this = this,
                allWidth = 0,
                autoCount = 0;
            for (var i = 0, len = this.opts.items.length; i < len; ++i) {
                var w = this.opts.items[i].width;
                var isNum = !(typeof w === 'string' || !w);
                tmp[i] = isNum ? parseInt(w) : 'auto';
                if (isNum) {
                    allWidth = allWidth + tmp[i];
                } else {
                    autoCount++;
                }
            }
            if (autoCount > 0) {
                var avgWidth = (_this.jqObj.width() - allWidth) / autoCount;
                for (var k in tmp) {
                    if (tmp[k] === 'auto') {
                        tmp[k] = avgWidth;
                    }
                }
            }
            return tmp;
        },
        resize: function () {
            var allWidth = this.jqObj.width(),
                acfwidth = 0;
            var autoIts = [];
            this.jqObj.children(".k_layout_item").each(function () {
                var $t = $(this);
                if ($t.data("width") === 'auto') {
                    autoIts.push($t);
                }
                acfwidth = acfwidth + $t.outerWidth();
            });
            var len = autoIts.length;
            var diffw = allWidth - acfwidth;
            var avgW = diffw / len;
            for (var i = 0, l = autoIts.length; i < l; ++i) {
                var w = autoIts[i].width();
                autoIts[i].width(w + avgW);
            }
        },
        /**
         * args:{title:'标题',iconCls:'图标样式'}/args=title,
         * panelIdx:模板索引
         ***/
        setTitle: function (args, panelIdx) {
            this.panels[panelIdx].setTitle(args);
        },
        /**
         *panelIdx:面板的索引、对应items里面的数据下标,
         args={
            url: null,//url地址
            dataType:'html/json/iframe',
            title:'设置该项会改变标题，可是不设置',
            iconCls:'设置新的图标，可是不设置'
         }
         * panelIdx:模板索引
         **/
        load: function (args, panelIdx) {
            if (args.title || args.iconCls) {
                this.setTitle(args, panelIdx);
            }
            this.panels[panelIdx].load(args);
        },
        /**更新内容
         *content：内容
         * panelIdx :模板索引
         * ****/
        updateContent: function (content, panelIdx) {
            var $p = this.panels[panelIdx];
            $p.updateContent(content);
        },
        /**获取iframe
         * panelIdx :模板索引
         * ****/
        getIfr: function (panelIdx) {
            return this.panels[panelIdx].getIfr();
        },
        /**
         * 获取当前的url
         * **/
        getUrl: function (panelIdx) {
            return this.panels[panelIdx].opts.url;
        },
        /**销毁***/
        destroy: function () {
            for (var i = 0, len = this.panels.length; i < len; ++i) {
                this.panels[i].destroy();
            }
            this["super"].destroy.call(this);
            this.panels = null;
        }
    };
    $B["Layout"] = Layout;
    return Layout;
}));/**
 * 2019-05-15 数据data对象添加一个toJson api destroy内调用clearWatchers清除数据对象上的观察者
 * 2019-05-13 新增对k_window_input支持适用于属性表单的window选择输入input
 * 2019-05-03 支持 bui中的calender时间日期支持
 * **/
(function (global, factory) {
    if (typeof define === 'function' && define.amd) {
        define(['jquery'], function ($) {
            return factory(global, $);
        });
    } else {
        factory(global, $);
    }
}(typeof window !== "undefined" ? window : this, function (window, $) {
    "use strict";
    var noCompileAttrs = {
        "type": true,
        "name": true,
        "watcher": true,
        "id": true
    };
    var $B = window["$B"] ? window["$B"] : {};
    String.prototype.trim = function () {
        return this.replace(/(^\s*)|(\s*$)/g, "");
    };
    String.prototype.leftTrim = function () {
        return this.replace(/(^\s*)/g, "");
    };
    String.prototype.rightTrim = function () {
        return this.replace(/(\s*$)/g, "");
    };
    var bindReg = /\{\s*\{(.*)\}\s*\}/;
    var expressCache = {};
    var clearExpressCacheTimer;

    function getExpressArray(textContent) {
        if (expressCache[textContent]) {
            return expressCache[textContent];
        }
        var res = textContent.match(/\{\{((?!\}\}).)+\}+/g);
        var expressArray = [];
        for (var i = 0, len = res.length; i < len; ++i) {
            var s = res[i].replace(/\s*\{\{\s*/, "").replace(/\s*\}\}\s*/, "");
            expressArray.push(s);
        }
        expressCache[textContent] = expressArray;
        clearTimeout(clearExpressCacheTimer);
        clearExpressCacheTimer = setTimeout(function () {
            expressCache = {};
        }, 1200);
        return expressArray;
    }
    var funcBodyCache = {};
    var clearFuncBodyCacheTimer;

    function getfuncBody(express) {
        var fbody = funcBodyCache[express];
        if (fbody) {
            return fbody;
        }
        fbody = express.replace(/{\s*\{/g, "").replace(/\}\s*\}/g, "").trim();
        funcBodyCache[express] = fbody;
        clearTimeout(clearFuncBodyCacheTimer);
        clearFuncBodyCacheTimer = setTimeout(function () {
            funcBodyCache = {};
        }, 1200);
        return fbody;
    }
    function clearWatchers(obj){
        if(obj){
            var keys = Object.keys(obj);
            var key ,v;
            for (var i = 0, len = keys.length; i < len; ++i) {
                key = keys[i];
                if(key === "_$watchers" ){
                    obj[key] = [];
                }else {
                    v = obj[key];
                    if (typeof v !== "toJson" && typeof v !== "function"  && key !== "_$path") {
                        if ($.isPlainObject(v)) {
                            clearWatchers(v);
                        }
                    }
                }
            }
        }        
    }
    /**
     * 递归对象自身属性
     * ***/
    function loopSelfProps(obj){
        var keys = Object.keys(obj);
        var key, v,json = {};
        for (var i = 0, len = keys.length; i < len; ++i) {
            key = keys[i];
            v = obj[key];
            if (typeof v !== "toJson" && typeof v !== "function" && key !== "_$watchers" && key !== "_$path") {
                if ($.isPlainObject(v)) {
                    json[key] = loopSelfProps(v);
                } else {
                    json[key] = v;
                }
            }
        }
        return json;
    }

    /***
     * 观察者，属性值变更时候，通知观察者更新UI，UI更新时候，通知观察者更新属性
     * 一个绑定属性一个wathcer，一个wathcer里面可能有多个绑定的data字段属性,
     * wather可能同时监听着不同的数据节点
     * 从expressArray中解析出数据节点，及对应的属性名称，记录到wather中
     * ***/
    function Watcher(vm, node, replaceContent, attrName) {
        this.vm = vm;
        this.attrName = attrName ? attrName.toLowerCase() : attrName;
        this.el = node;
        this.$el = $(this.el);
        this.nodeName = node.nodeName;
        this.replaceContent = replaceContent;
        var expressArray = getExpressArray(replaceContent);
        this.methodKeys = [];
        this.propPathArray = [];
        this.propObjectArray = [];
        var express;
        var mapHasset = {}; //防止重复解析 注册
        var i, len;
        //解析出属性对象，将watcher注册到属性对象上
        for (i = 0, len = expressArray.length; i < len; ++i) {
            express = expressArray[i];
            express = getfuncBody(express);
            this.methodKeys.push(express);
            var expArray = express.match(/this\.data\.[^\s*]+/g);
            for (var j = 0, jlen = expArray.length; j < jlen; ++j) {
                express = expArray[j];
                if (!mapHasset[express]) {
                    mapHasset[express] = true;
                    var extractArray = this.vm.extractPropObject(express);
                    for (var k = 0, klen = extractArray.length; k < klen; k++) {
                        var extract = extractArray[k];
                        var propObject = extract.propObject;
                        this.propPathArray.push(extract.propPath);
                        //属性对象上注册本观察者
                        if (!propObject._$watchers) {
                            propObject._$watchers = [];
                        }
                        propObject._$watchers.push(this);
                        this.propObjectArray.push(propObject);
                    }
                }
            }
        }
        var _this = this;
        if (this.attrName === "express") { //自定义解析，自定义处理watcher
            var watcher = this.$el.attr("watcher");
            if (watcher && typeof this.vm[watcher] === "function") {
                this.vm[watcher](this);
            }
        } else {
            var isBindUserInput = this.el.nodeType === 1;
            var isTextArea = this.el.parentNode.nodeName === "TEXTAREA"; //对TEXTAREA进行用户输入绑定
            if (isTextArea) {
                isBindUserInput = true;
            }
            //绑定UI用户操作--->data的联动            
            if (isBindUserInput) {
                var updateTimer = 100;
                //var elType = this.$el.attr("type").toLowerCase();
                //console.log(" elType == " + elType + " this.attrName = " + this.attrName);
                this.userInputTimer;
                var eventName, eventEl = this.$el;
                if (this.attrName === "value" || isTextArea) {
                    eventName = "input";
                    if (isTextArea) {
                        eventEl = $(this.el.parentNode);
                    }
                } else if (this.attrName === "checked" || this.attrName === "selected") { //radio、checkbox、select联动
                    updateTimer = 0;
                    eventName = "change";
                    if (this.nodeName === "OPTION" && this.attrName === "selected") { //下拉选框
                        eventEl = this.$el.parent();
                        if (eventEl.data("hasBindWatcher")) {
                            eventName = undefined;
                        } else {
                            eventEl.data("hasBindWatcher", true);
                        }
                    }
                }
                if (eventName) {
                    eventEl.on(eventName + ".mvvm", function () {
                        if (_this.propChangeUpdating) { //避免循环联动
                            //console.log("避免循环联动 >>>>>>> propChangeUpdating");
                            return false;
                        }                        
                        var el = this;
                        var $t = $(this);
                        var txt = $t.val();
                        var eleType = $t.attr("type");
                        if(eleType){
                            eleType = eleType.toLowerCase();
                        }
                        clearTimeout(_this.userInputTimer);
                        if (eleType === "radio") { //
                            var name = $t.attr("name");
                            var allRadio = _this.vm.$form.find("input[name=" + name + "]");
                            allRadio.each(function () {
                                var $r = $(this);
                                if (this !== el) {
                                    $r.removeAttr("checked");
                                } else {
                                    $r.attr("checked", "checked").prop("checked", true);
                                }
                            });
                            //no2update不需要再对统一组name的radio属性set监听更新
                            allRadio.data("no2update", true);
                            setTimeout(function () {
                                allRadio.removeData("no2update");
                            }, 100);
                        } else if ($t[0].nodeName === "SELECT") {
                            //no2update不需要对同一组的option进行属性set监听更新
                            var opts = $t.children().data("no2update", true);
                            opts.each(function () {
                                var opt = $(this);
                                if (txt === opt.val()) {
                                    opt.prop("selected", true).attr("selected", "selected");
                                } else {
                                    opt.prop("selected", false).removeAttr("selected");
                                }
                            });
                            setTimeout(function () {
                                opts.removeData("no2update");
                            }, 100);
                        }
                        _this.userInputTimer = setTimeout(function () {                           
                            var paths = _this.propPathArray[0].split(".");
                            var pName = paths[paths.length - 1];
                            var propObject = _this.propObjectArray[0];
                            var oldValue = propObject[pName];
                            if (!$.isPlainObject(oldValue)) {
                                if (typeof oldValue === "number" && txt !== "") {
                                    if (oldValue % 1 === 0) {
                                        txt = parseInt(txt);
                                    } else {
                                        txt = parseFloat(txt);
                                    }
                                    propObject[pName] = txt;
                                } else {
                                    propObject[pName] = txt;
                                }
                            }
                        }, updateTimer);
                    });
                }
            }
        }
    }
    Watcher.prototype = {
        update: function (target, propName, newValue, oldValue) {
            if (this.$el.data("no2update")) {
                return;
            }
            this.propChangeUpdating = true; //避免循环联动
            var path = target._$path ? target._$path + "." + propName : propName;
            if (this.need2Update(path) && newValue !== oldValue) {
                if (this.attrName === "express") { //自定义解析
                    this.expressUpater();
                } else if (this.el.nodeType === 3) { //文本节点更新
                    this.textUpdater();
                } else if (this.nodeName === "OPTION" && this.attrName.toLowerCase() === "selected") { //下拉项目更新器
                    this.selectUpdater();
                } else if (this.nodeName === "INPUT" && this.$el.attr("type") === "radio") {
                    this.radioUpdater();
                } else { //其他节点更新
                    this.elUpdater();
                }
                var _this = this;
                setTimeout(function () {
                    _this.propChangeUpdating = false;
                }, 20);
            } else {
                this.propChangeUpdating = false;
            }
        },
        need2Update: function (path) {
            var res = false;
            for (var i = 0, len = this.propPathArray.length; i < len; ++i) {
                var p = this.propPathArray[i];
                if (p === path) {
                    res = true;
                    break;
                } else if (p.indexOf(path + ".") === 0) { //子节点替换
                    res = true;
                    break;
                }
            }
            return res;
        },
        /**express自定义更新解析**/
        expressUpater: function () {
            var mKey;
            for (var i = 0, len = this.methodKeys.length; i < len; ++i) {
                mKey = this.methodKeys[i];
                this.vm.callExpressFuntion(mKey, this.$el);
            }
        },
        //radio更新器
        radioUpdater: function () {
            var _this = this;
            _this._invokeMethods(function (mKey, value) {
                if (value) {
                    _this.$el.attr("checked", "checked").prop("checked", true);
                } else {
                    _this.$el.removeAttr("checked").prop("checked", false);
                }
            });
        },
        /**下拉更新项**/
        selectUpdater: function () {
            var _this = this;
            _this._invokeMethods(function (mKey, value) {
                if (value) {
                    _this.$el.prop("selected", true).attr("selected", "selected");
                } else {
                    _this.$el.prop("selected", false).removeAttr("selected");
                }
            });
        },
        /**文本节点更新器**/
        textUpdater: function () {
            var text = this.replaceContent,
                need2Update = false;
            this._invokeMethods(function (mKey, value) {
                if (typeof value !== "undefined") {
                    mKey = mKey.replace(/\+/g, "\\+").replace(/\-/g, "\\-").replace(/\*/g, "\\*");
                    var exp = "{\\s*{\\s*" + mKey + "\\s*}\\s*}";
                    var reg = new RegExp(exp, "g");
                    text = text.replace(reg, value);
                    need2Update = true;
                }
            });
            if (need2Update) {
                this.el.textContent = text;
                this.el.nodeValue = text;
                this.el.data = text;
                if(this.el.parentNode.nodeName === "TEXTAREA"){//兼容TEXTAREA
                    this.el.parentNode.value = text;
                    this.el = this.el.parentNode.firstChild;
                }
            }
        },
        /**元素属性更新器**/
        elUpdater: function () {
            var _this = this;
            this._invokeMethods(function (mKey, value) {
                _this.$el.attr(_this.attrName, value);
                if (_this.attrName === "value") {
                    _this.$el.val(value);
                }
            });
        },
        /***调用所有监听的function***/
        _invokeMethods: function (callFn) {
            var mKey, value;
            for (var i = 0, len = this.methodKeys.length; i < len; ++i) {
                mKey = this.methodKeys[i];
                value = this.vm.callExpressFuntion(mKey);
                callFn(mKey, value);
            }
        },
        destroy: function () {
            for (var p in this) {
                if (this.hasOwnProperty(p)) {                   
                    delete this[p];
                }
            }
        }
    };
    /***
     * 定义html模板编译解析器
     * 编译解析模板，将模板绑定与data属性进行双向关联
     * ***/
    function Compiler(vm) {
        this.vm = vm;
        this.el = vm.el;
        this.$el = vm.$form;
        this.data = vm.data;
        this.watchers = [];
        this.compile(this.el);
    }
    Compiler.prototype = {
        compile: function (el) {
            this.compileingEl = el;
            if (el.nodeType === 3) {
                this.compileTextNode(el);
            } else if (el.nodeType === 1) {
                this.compileElement(el);
            }
        },
        /**解析节点元素
         * 解析元素的属性
         * **/
        compileElement: function (el) {
            var nodeName = el.nodeName;
            if (nodeName === "SCRIPT" || nodeName === "STYLE") {
                return;
            }
            var attributes = el.attributes;
            var me = this;
            var $el = $(el);
            var attr, i, len;
            //编译元素属性 
            for (i = 0, len = attributes.length; i < len; ++i) {
                attr = attributes[i];
                if(!attr){
                    continue;
                }
                var attrName = attr.name;
                if (!noCompileAttrs[attrName]) {
                    var expValue = attr.value;
                    var value;
                    if (bindReg.test(expValue)) {
                        expValue = expValue.replace(/\{\s*\{/g, "{{");
                        expValue = expValue.replace(/\}\s*\}/g, "}}");
                        //console.log("compileElement >>>>>>>>>>>>>>>>>>>>> attrName = " + attrName + expValue);
                        if (nodeName === "INPUT" && attrName === "value") {
                            value = me.invokeExpressMethod(expValue);
                            $el.attr("value", value);
                            //创建一个节点Watcher，将Watcher注册到对应的属性节点节点上
                            me.watchers.push(new Watcher(me.vm, el, expValue, attrName));
                        } else if (nodeName === "INPUT" && attrName === "checked") { //表达式属性                        
                            value = me.invokeExpressMethod(expValue);
                            $el.removeAttr("checked");
                            if (value) {
                                $el.attr("checked", "checked");
                                $el.prop("checked", true);
                            }
                            me.watchers.push(new Watcher(me.vm, el, expValue, attrName));
                        } else if (nodeName === "OPTION" && attrName === "selected") { //表达式属性
                            value = me.invokeExpressMethod(expValue);
                            $el.removeAttr("selected");
                            if (value) {
                                $el.attr("selected", "selected");
                                $el.prop("selected", true);
                            }
                            me.watchers.push(new Watcher(me.vm, el, expValue, attrName));
                        } else if (attrName === "express") { //扩展解析
                            var extFunctionBody = getfuncBody(expValue);
                            var extFunction = me.makeExpressionFunction(extFunctionBody);
                            extFunction.call(me.vm, $el);
                            me.watchers.push(new Watcher(me.vm, el, expValue, attrName));
                        }
                        // else if (attrName === "style") {
                        //     //console.log("待完成 ");
                        // } else if (attrName === "class") {
                        //     //console.log("待完成 ");
                        // } 
                        else { //其他属性
                            value = me.invokeExpressMethod(expValue);
                            $el.attr(attr.name, value);
                            me.watchers.push(new Watcher(me.vm, el, expValue, attrName));
                        }
                    }
                }
            }
            // });
            //递归子元素           
            var childNodes = el.childNodes;
            var child;
            for (i = 0, len = childNodes.length; i < len; ++i) {
                child = childNodes[i];
                this.compile(child);
            }
        },
        /**解析文本节点**/
        compileTextNode: function (node) {
            var textContent = node.textContent;
            if (bindReg.test(textContent)) {
                textContent = textContent.replace(/\{\s*\{/g, "{{");
                textContent = textContent.replace(/\}\s*\}/g, "}}");
                var value = this.invokeExpressMethod(textContent);
                if (typeof value !== "undefined") {
                    node.textContent = value;
                    //创建一个节点Watcher，将Watcher注册到对应的属性节点节点上
                    this.watchers.push(new Watcher(this.vm, node, textContent));
                }
            }
        },
        getExpressMethod: function (textContent) {
            return this.invokeExpressMethod(textContent, true);
        },
        invokeExpressMethod: function (textContent, isGetMethod) {
            var res = getExpressArray(textContent);
            if (res) {
                var returnValue = textContent,
                    express, funcBody, expFn, tmpVal, reg;
                for (var j = 0, len1 = res.length; j < len1; ++j) {
                    express = res[j];
                    funcBody = getfuncBody(express);
                    expFn = this.vm.expressMethodCache[funcBody];
                    if (!expFn) {
                        expFn = this.makeExpressionFunction(funcBody);
                    }
                    if (isGetMethod) {
                        return expFn;
                    }
                    tmpVal = expFn.call(this.vm);
                    if (typeof tmpVal === "boolean") {
                        return tmpVal;
                    }
                    express = express.replace(/\+/g, "\\+").replace(/\-/g, "\\-").replace(/\*/g, "\\*");
                    express = express.replace(/\(/g, "\\(").replace(/\)/g, "\\)");
                    express = express.replace(/\{/g, "\\{").replace(/\}/g, "\\}");
                    reg = new RegExp(express, "g");
                    returnValue = returnValue.replace(reg, tmpVal);
                }
                returnValue = returnValue.replace(/\{\{/g, "").replace(/\}\}/g, "");
                return returnValue;
            }
        },
        makeExpressionFunction: function (expression) {
            var fn = this.vm.expressMethodCache[expression];
            if (!fn) {
                var funcBody;
                if (expression.indexOf("return") > 0) {
                    funcBody = expression;
                } else {
                    funcBody = 'return ' + expression + ';';
                }
                fn = new Function("el", funcBody);
                this.vm.expressMethodCache[expression] = fn;
            }
            return fn;
        },
        destroy: function () {
            for(var i = 0 ,len = this.watchers.length ; i < len ;++i){
                this.watchers[i].destroy();
            }
            for (var p in this) {
                if (this.hasOwnProperty(p)) {                   
                    delete this[p];
                }
            }
        }
    };
    /*****
     * 属性包装
     * 利用Object.defineProperty对data进行同名属性覆盖定义
     * 利用闭包作用域确保重新定义的get/set是对原生data属性值的封装
     * 利用get/set观察赋值、取值
     * ******/
    function Observer(dataObj, vm) {
        this.data = dataObj;
        this.vm = vm;
        var me = this,
            paths,
            key,
            value;
        var keys = Object.keys(dataObj);
        for (var i = 0, len = keys.length; i < len; ++i) {
            key = keys[i];
            if (key !== "_$watchers" && key !== "_$path" && key !== "toJson") {
                paths = [];
                value = dataObj[key];
                if ($.isPlainObject(value)) {
                    paths.push(key);
                }
                me.getSetBuild(dataObj, key, value, paths);
            }
        }
    }
    Observer.prototype = {
        /**递归属性**/
        forProps: function (dataObj, paths) {
            if (!dataObj || !$.isPlainObject(dataObj)) {
                return;
            }
            dataObj["_$path"] = paths.join(".");
            var me = this,
                key, val, pathCopy;
            var keys = Object.keys(dataObj);
            for (var i = 0, len = keys.length; i < len; ++i) {
                key = keys[i];
                if (key !== "_$watchers" && key !== "_$path" && key !== "toJson") {
                    val = dataObj[key];
                    pathCopy = paths.slice();
                    if ($.isPlainObject(val)) {
                        pathCopy.push(key);
                    }
                    me.getSetBuild(dataObj, key, val, pathCopy);
                }
            }
        },
        /**get/set重新定义包装**/
        getSetBuild: function (data, key, value, paths) {
            var me = this;
            this.forProps(value, paths); //递归包装
            //修复
            Object.defineProperty(data, key, {
                enumerable: true,
                configurable: true,
                set: function (newValue) {
                    if ((value + "") === (newValue + "")) {
                        return;
                    }
                    var oldValue = value;
                    //拷贝watcher到新的对象值上
                    if ($.isPlainObject(value) && $.isPlainObject(newValue)) {
                        me.copyWatcher(value, newValue);
                    }
                    value = newValue;
                    me.forProps(value, paths); //递归包装新值
                    me.onSet(this, key, newValue, oldValue);
                },
                get: function () {
                    return value;
                }
            });
        },
        /**
         * 递归
         * 拷贝watcher到新的对象值上 
         * **/
        copyWatcher: function (oldObject, newObject) {
            if (oldObject["_$watchers"]) {
                newObject["_$watchers"] = oldObject["_$watchers"];
                oldObject["_$watchers"] = undefined;
            }
            if (oldObject["_$path"]) {
                newObject["_$path"] = oldObject["_$path"];
                oldObject["_$path"] = undefined;
            }
            var me = this,
                oldObj, prop;
            var props = Object.keys(oldObject);
            for (var i = 0, len = props.length; i < len; ++i) {
                prop = props[i];
                oldObj = oldObject[prop];
                if (typeof oldObj === "object") {
                    var newObj = newObject[prop];
                    if (typeof newObj === "object") {
                        me.copyWatcher(oldObj, newObj);
                    }
                }
            }
        },
        onSet: function (target, propName, newValue, oldValue) {
            if (target["_$watchers"]) { //是否存在观察者！！
                for (var i = 0, len = target["_$watchers"].length; i < len; ++i) {
                    var watcher = target["_$watchers"][i];
                    watcher.update(target, propName, newValue, oldValue);
                }
            }
            var _this = this;
            if (typeof this.vm.onChanged === "function") {
                _this.vm.onChanged.call(_this.vm, target, propName, newValue, oldValue);
                // clearTimeout(_this.onChangedTimer);
                // _this.onChangedTimer = setTimeout(function () {
                //     _this.vm.onChanged.call(_this.vm, target, propName, newValue, oldValue);
                // }, 300);
            }
        },
        destroy: function () {
            for (var p in this) {
                if (this.hasOwnProperty(p)) {                   
                    delete this[p];
                }
            }
        }
    };
    /**
     * mvvm定义
     * **/
    function Mvm(options) {
        this.el = typeof options.el === "string" ? document.getElementById(options.el) : options.el;
        this.$form = $(this.el);
        this.options = options;
        this.data = options.data;
        this.onChanged = options.onChanged;
        this.expressMethodCache = {}; //表达式动态function缓存
        this.pathObjectsCache = {};
        this.initing = true;
        //处理自定义的comboxWatcher 、 comboxExpress
        this._attachDiyRegiste(this.options.registeWatchers);
        this._attachDiyRegiste(this.options.registeExpress);
        this.observer = new Observer(this.data, this); //先对属性进行get/set包装 
        this.compiler = new Compiler(this); //编译解析模板，将模板绑定与data属性进行双向关联
        var _this = this;
        setTimeout(function(){
            _this.initing = true;
        },50);
        //补偿一个toJson API
        if(typeof this.data.toJson !== "function"){
            this.data.toJson = function(){                
                var json = {};
                var v, key;
                var keys = Object.keys(this);
                for (var i = 0, len = keys.length; i < len; ++i) {
                    key = keys[i];
                    v = this[key];
                    if ( typeof v !== "function" && key !== "toJson" && key !== "_$watchers" && key !== "_$path") {
                        if ($.isPlainObject(v)) {
                            json[key] = loopSelfProps(v);
                        } else {
                            json[key] = v;
                        }
                    }
                }
                //console.log("data.toJson >>>>");
                return json;
            };
        }
    }
    Mvm.prototype = {
        destroy: function () {
           // console.log("destroy >>>  mvvm obj");
            //解除数据对象上的_$watchers
            clearWatchers(this.data);
            this.observer.destroy();
            this.compiler.destroy();
            for (var p in this) {
                if (this.hasOwnProperty(p)) {                   
                    delete this[p];
                }
            }
        },
        /***
         * 根据路径抽取属性对象,采用缓存避免重复解析提取
         * path 可能是个逻辑表达式 this.data.form.sex === 1 ? true : false
         * 也可能是 this.data.form.userName
         * propObject:属性对象，propNames属性名称集合
         * ***/
        extractPropObject: function (path) {
            var cacheKey = path;
            var retArray = this.pathObjectsCache[cacheKey];
            if (retArray) {
                return retArray;
            }
            var res = path.match(/this\.data\.[^\s+|^,]+/g);
            retArray = [];
            var rootObject = this.data,
                tmpObj,
                tmpArray;
            for (var j = 0, jlen = res.length; j < jlen; ++j) {
                path = res[j].replace("this.data.", "");
                tmpObj = rootObject;
                if (path.indexOf(".") > 0) {
                    tmpArray = path.split(".");
                    for (var i = 0, len = tmpArray.length - 1; i < len; ++i) {
                        if (i < len) {
                            tmpObj = tmpObj[tmpArray[i]];
                        }
                    }
                }
                retArray.push({
                    propObject: tmpObj,
                    propPath: path
                });
            }
            this.pathObjectsCache[cacheKey] = retArray;
            return retArray;
        },
        //附加自定义的comboxWatcher 、 comboxExpress
        _attachDiyRegiste: function (regiter) {
            var keys, i, len, fn, key;
            if ($.isPlainObject(regiter)) {
                keys = Object.keys(regiter);
                for (i = 0, len = keys.length; i < len; ++i) {
                    key = keys[i];
                    fn = regiter[key];
                    if (typeof this[key] === "function") {
                        console.log("key[" + key + "]已经存在！");
                        continue;
                    }
                    if (typeof fn === "function") {
                        this[key] = fn;
                    }
                }
            }
        },
        /**
         * 注册监听器
         * **/
        registeWatcher: function (watcherName, wathcerFn) {
            if (typeof this[watcherName] === "function") {
                console.log("watcher[" + watcherName + "]已经存在！");
            }
            this[watcherName] = wathcerFn;
            return this;
        },
        /**
         * 注册表达式处理解析器
         * **/
        registeExpress: function (expressName, expressFn) {
            if (typeof this[expressName] === "function") {
                console.log("express[" + expressName + "]已经存在！");
            }
            this[expressName] = expressFn;
            return this;
        },
        /**
         * 编译某个元素
         * **/
        compile: function (el) {
            if (el.css) {
                el = el[0];
            }
            this.compiler.compile(el);
            return this;
        },
        /***
         * 调用表达式对应的function
         * ***/
        callExpressFuntion: function (express, args) {
            var m = this.expressMethodCache[express];
            if (m) {
                return m.call(this, args);
            }
            return undefined;
        },
        _forProps: function (obj, json) {
            var _this = this,
                v, key;
            var keys = Object.keys(obj);
            for (var i = 0, len = keys.length; i < len; ++i) {
                key = keys[i];
                v = obj[key];
                if (typeof v !== "function" && key !== "_$watchers" && key !== "_$path") {
                    if ($.isPlainObject(v)) {
                        json[key] = {};
                        _this._forProps(v, json[key]);
                    } else {
                        json[key] = v;
                    }
                }
            }
        },
        getJson: function () {
            var json = {};
            var _this = this,
                v, key;
            var keys = Object.keys(this.data);
            for (var i = 0, len = keys.length; i < len; ++i) {
                key = keys[i];
                v = _this.data[key];
                if (typeof v !== "toJson" && typeof v !== "function" && key !== "_$watchers" && key !== "_$path") {
                    if ($.isPlainObject(v)) {
                        json[key] = {};
                        _this._forProps(v, json[key]);
                    } else {
                        json[key] = v;
                    }
                }
            }
            if(this.options.onGetJson){
                this.options.onGetJson(json);
            }
            return json;
        },
        /**
         * 复选框监听器
         * **/
        checkboxWather: function (wather) {
            var propObject = wather.propObjectArray[0];
            var propPaths = wather.propPathArray[0].split(".");
            var propName = propPaths[propPaths.length - 1];
            wather.$el.on("click", function () {
                var $t = $(this);
                var val = $t.val();
                var propVals = propObject[propName];
                var isNumeric = false;
                var isArray = $.isArray(propVals);
                var isDotSplit = false;
                if (isArray) {
                    if (propVals.length > 0) {
                        isNumeric = $.isNumeric(propVals[0]);
                    }
                } else {
                    isDotSplit = propVals.indexOf(";") > 0;
                    isNumeric = false;
                    if (propVals === "") {
                        propVals = [];
                    } else {
                        if (isDotSplit) {
                            propVals = propVals.split(";");
                        } else {
                            propVals = propVals.split(",");
                        }
                    }
                }
                if (isNumeric) {
                    val = parseInt(val);
                }
                var newValues = propVals;
                if ($t.prop("checked")) {
                    $t.attr("checked", "checked");
                    propVals.push(val);
                } else {
                    $t.removeAttr("checked");
                    newValues = [];
                    for (var i = 0, len = propVals.length; i < len; ++i) {
                        if (propVals[i] !== "" && propVals[i] !== val) {
                            newValues.push(propVals[i]);
                        }
                    }
                }
                if (!isArray) {
                    if (isDotSplit) {
                        propObject[propName] = newValues.join(";");
                    } else {
                        propObject[propName] = newValues.join(",");
                    }
                }
            });
        },
        /**
         *复选框特有的解析 
         **/
        checkboxExpress: function (propVal, el) {
            var v = el.val();
            if (!$.isArray(propVal)) {
                if (propVal.indexOf(",") > 0) {
                    propVal = propVal.split(",");
                } else if (propVal.indexOf(";") > 0) {
                    propVal = propVal.split(";");
                }
            }
            var isChecked = false;
            for (var i = 0, len = propVal.length; i < len; ++i) {
                if (v === (propVal[i] + "")) {
                    isChecked = true;
                    break;
                }
            }
            if (isChecked) {
                el.prop("checked", true).attr("checked", "checked");
            } else {
                el.prop("checked", false).removeAttr("checked");
            }
        },
        kRadioWatcher: function (watcher) {
            var $el = watcher.$el;
            var propObject = watcher.propObjectArray[0];
            var propName = watcher.propPathArray[0];
            $el.children("input").on("change", function () {
                var v = $(this).val();
                var oldValue = propObject[propName];
                var isNumeric = $.isNumeric(oldValue);
                if (isNumeric) {
                    propObject[propName] = parseInt(v);
                } else {
                    propObject[propName] = v;
                }
            });
        },
        kRadioExpress: function (data, el) {
            var $el = $(el);
            $el.find("input[type=radio]").each(function () {
                var box = $(this);
                var v = box.val();
                if (v === (data + "")) {
                    box.attr("checked", "checked").prop("checked", true);
                } else {
                    box.removeAttr("checked").prop("checked", false);
                }
            });
        },
        kcheckBoxWatcher: function (watcher) {
            var $el = watcher.$el;
            var propObject = watcher.propObjectArray[0];
            var propName = watcher.propPathArray[0];
            $el.children("input").on("change", function () {
                var $input = $(this);
                var propVal = propObject[propName];
                var valArray = [];
                var joinChart;
                if (propVal !== "") {
                    if (propVal.indexOf(";") > 0) {
                        valArray = propVal.split(";");
                        joinChart = ";";
                    } else {
                        valArray = propVal.split(",");
                        joinChart = ",";
                    }
                }
                var v = $input.val();
                if ($input.prop("checked")) {
                    valArray.push(v);
                } else {
                    var newArray = [];
                    for (var i = 0, len = valArray.length; i < len; ++i) {
                        if (v !== valArray[i]) {
                            newArray.push(valArray[i]);
                        }
                    }
                    valArray = newArray;
                }
                propObject[propName] = valArray.join(joinChart);
            });
        },
        kcheckBoxExpress: function (data, el) {
            var $el = $(el);
            $el.find("input[type=checkbox]").each(function () {
                var box = $(this);
                var v = box.val();
                var isChecked = false;
                var patt1;
                if (data.indexOf(";") >= 0) {
                    patt1 = new RegExp(";" + v + ";|;" + v + "|" + v + ";");
                    isChecked = patt1.test(data);
                } else if (data.indexOf(",") >= 0) {
                    patt1 = new RegExp("," + v + ",|," + v + "|" + v + ",");
                    isChecked = patt1.test(data);
                } else {
                    isChecked = data === v;
                }
                if (isChecked) {
                    box.attr("checked", "checked").prop("checked", true);
                } else {
                    box.removeAttr("checked").prop("checked", false);
                }
            });
        },
        /**
         * combox观察者解析
         * **/
        kcomboxWatcher: function (wather) {
            var combox = wather.$el.data("combox");
            var propObject = wather.propObjectArray[0];
            var propPath = wather.propPathArray[0];
            var propValue, userSelIds, ids, i, len;
            if (combox.opts.checkbox) { //多选
                ids = combox.getCheckedIds();
                userSelIds = [];
                for (i = 0, len = ids.length; i < len; ++i) {
                    if(ids[i].id !== ""){
                        userSelIds.push(ids[i].id);
                    }                    
                }
                propValue = userSelIds.join(",");
            } else { //单选
                propValue = combox.jqObj.data("id");
            }
            //通过wather更新userSeletions属性
            if((propObject[propPath] + "") !== propValue){
                propObject[propPath] = propValue;
            }            
            combox.regiterFn("onWatcher", function () {
                if (this.opts.checkbox) { //多选
                    var ids = this.getCheckedIds();
                    userSelIds = [];
                    for (i = 0, len = ids.length; i < len; ++i) {
                        if(ids[i].id !== ""){
                            userSelIds.push(ids[i].id);
                        }
                    }
                    propValue = userSelIds.join(",");
                } else {
                    propValue = this.jqObj.data("id");
                }
                if((propObject[propPath] + "") !== propValue){
                    propObject[propPath] = propValue;
                }
            });
        },
        kcomboxExpress: function (data, $el) { //通过数据反向修改combox，这里不做处理           
            var combox = $el.data("combox");
            combox.setCheckDatas(data);
        },
        /***
         * 时间日期控件解析支持
         * ***/
        kcalendarWatcher:function(wather){
            var calender = wather.$el.data("calender");
            var propObject = wather.propObjectArray[0];
            var propPath = wather.propPathArray[0];
            calender.regiterFn("onWatcher", function () {                
                propObject[propPath] = this.target.val();
            });
        },
        kcalendarExpress:function(data, el){
            if(data !== ""){
                var $el = $(el);
                var calender = $el.data("calender");
                calender.setValue(data);
            }       
        },
        /**
         * 树控件联动支持 k_tree_ul
         * ***/
        ktreeExpress:function(data, el){
            var $el = $(el);
            var treeIns = $el.data("treeIns");
            treeIns.setCheckDatas(data); 
        },  
        ktreeWatcher:function(wather){
            var treeIns = wather.$el.data("treeIns");
            var propObject = wather.propObjectArray[0];
            var propPath = wather.propPathArray[0];
            var propValue = propObject[propPath];
            treeIns.regiterFn("onWatcher", function () {
                var idArr = this.getCheckedData({
                    onlyId: true,
                });
                var tmp = [];
                for(var i = 0 ,len = idArr.length ; i < len ;++i){
                    tmp.push(idArr[i].id);
                }
                propValue = tmp.join(",");
                if((propObject[propPath] + "") !== propValue){
                    propObject[propPath] = propValue;
                }
            });
          
        },
        /**
         * window弹窗选择 input的解析 
         * **/
        kwindowInputExpress:function(data, el){
            var arr = data.split(",");
            var tmp,txtArr = [];
            for(var i = 0 ,len = arr.length ; i < len ; ++i){
                tmp = arr[i].split("___");
                txtArr.push(tmp[1]);
            }
            el.val(txtArr.join(",")).attr("_val",data);
        },
        kwindowInputWatcher:function(wather){
            var el = wather.$el;
            var propObject = wather.propObjectArray[0];
            var propPath = wather.propPathArray[0];
            //var propValue = propObject[propPath];
            el.on("change",function(){
                console.log("wather input change");
                var $t = $(this);
                var val = $t.attr("_val");
                var arr = val.split(",");
                var tmp,txtArr = [];
                for(var i = 0 ,len = arr.length ; i < len ; ++i){
                    tmp = arr[i].split("___");
                    txtArr.push(tmp[1]);
                }
                $t.val(txtArr.join(","));
                propObject[propPath] = val;
            });
        }   
    };
    $B.Mvvm = Mvm;
    window["$B"] = $B;
    return Mvm;
}));(function (global, factory) {
    if (typeof define === 'function' && define.amd) {
        define(['$B'], function (_$B) {
            return  factory(global, _$B);
        });
    } else {
        if(!global["$B"]){
            global["$B"] = {};
        }
        factory(global, global["$B"]);
    }
}(typeof window !== "undefined" ? window : this, function (window, $B) {
    var def = {
        pageSize: 15, //页大小
        height: 25,
        pageList: [15, 25, 30, 35, 40, 55], //页大小项
        page: 1, //当前页
        startpg: 1, //开始页
        buttons: 5, //页按钮数量
        position: 'right', // right center left
        summary: true //是否需要页大小，页总数汇总显示
    };

    function _create() {
        var last, next, prev, first;
        var nubWrap = $("<div style='float:left;' class='k_pagination_num_wrap k_box_size'></div>");
        var opts = this.opts;

        function click(e) {
            var $t = $(this);
            var flag = $t.data("pg");
            var curActived;
            if ($t.hasClass("k_pagination_disabled")) {
                return;
            }
            if (flag === "r") { //刷新
                var isTrigger = $t.data("isTrigger");
                if (isTrigger) {
                    createNum(opts.startpg);
                    createSum();
                } else {
                    setTimeout(function () {
                        opts.onClick(opts.page, opts.pageSize, opts.startpg);
                    }, 10);
                }
            } else if (flag === 1) { //第一页
                opts.startpg = 1;
                opts.page = 1;
                createNum(opts.startpg);
                setTimeout(function () {
                    opts.onClick(opts.page, opts.pageSize, opts.startpg);
                }, 10);
            } else if (flag === "mn") { //向前翻
                opts.startpg = opts.startpg + opts.buttons;
                if (opts.startpg <= 0) {
                    opts.startpg = 1;
                }
                opts.page = opts.startpg;
                createNum(opts.startpg);
                setTimeout(function () {
                    opts.onClick(opts.page, opts.pageSize, opts.startpg);
                }, 10);
            } else if (flag === "mp") { //向后翻
                opts.startpg = opts.startpg - opts.buttons;
                if (opts.startpg <= 0) {
                    opts.startpg = 1;
                }
                opts.page = opts.startpg;
                createNum(opts.startpg);
                setTimeout(function () {
                    opts.onClick(opts.page, opts.pageSize, opts.startpg);
                }, 10);
            } else if (flag === "l") { //最后一页            	
                opts.startpg = opts.pageCount - opts.buttons + 1;
                if (opts.startpg <= 0) {
                    opts.startpg = 1;
                }
                opts.page = opts.pageCount;
                createNum(opts.startpg);
                setTimeout(function () {
                    opts.onClick(opts.page, opts.pageSize, opts.startpg);
                }, 10);
            } else if (flag === 'p') { //前一页
                curActived = nubWrap.children(".actived").removeClass("actived");
                var activedPrev = curActived.prev();
                if (activedPrev.length > 0) {
                    opts.page = activedPrev.addClass("actived").data("pg");
                    if (opts.page === 1) {
                        first.addClass("k_pagination_disabled");
                        prev.addClass("k_pagination_disabled");
                    }
                } else {
                    opts.page = curActived.data("pg") - 1;
                    if (opts.page < 1) {
                        opts.page = 1;
                    }
                    opts.startpg = opts.page - opts.buttons + 1;
                    createNum(opts.startpg);
                }
                setTimeout(function () {
                    opts.onClick(opts.page, opts.pageSize, opts.startpg);
                }, 2);
            } else if (flag === 'n') { //下一页
                curActived = nubWrap.children(".actived").removeClass("actived");
                var activedNext = curActived.next();
                if (activedNext.length > 0) {
                    opts.page = activedNext.addClass("actived").data("pg");
                    if (opts.page === opts.pageCount) {
                        last.addClass("k_pagination_disabled");
                        next.addClass("k_pagination_disabled");
                    }
                } else {
                    opts.page = curActived.data("pg") + 1;
                    opts.startpg = opts.page;
                    createNum(opts.startpg);
                }
                setTimeout(function () {
                    opts.onClick(opts.page, opts.pageSize, opts.startpg);
                }, 10);
            }
            return false;
        }

        opts.pageCount = Math.ceil(opts.total / opts.pageSize) || 1; //总页数
        var wrap = this.jqObj.children();
        wrap.children().remove();
        var h = wrap.height();
        var fresh = $("<a style='line-height:" + h + "px;height:" + h + "px' class='k_pagination_fresh k_box_size'><i style='line-height:" + h + "px' class='fa fa-refresh'></i><div class='a_div'></div></a>").appendTo(wrap);
        fresh.click(click).data("pg", "r").hide();
        first = $("<a style='line-height:" + h + "px;height:" + h + "px' class='k_pagination_first k_box_size'><i style='line-height:" + h + "px' class='fa fa-angle-double-left'></i><div class='a_div'></div></a>").appendTo(wrap);
        first.children("i").removeAttr("class").text($B.config.firstPage);
        first.hide();
        first.click(click).data("pg", 1);
        prev = $("<a style='line-height:" + h + "px;height:" + h + "px' class='k_pagination_prev k_box_size'><i style='line-height:" + h + "px' class='fa fa-angle-left'></i><div class='a_div'></div></a>").appendTo(wrap);
        prev.children("i").removeAttr("class").text($B.config.prevPage);
        prev.click(click).data("pg", "p");
        if (opts.page === 1) {
            first.addClass("k_pagination_disabled");
            prev.addClass("k_pagination_disabled");
        }
        nubWrap.insertAfter(prev);

        function createNum(_st) {
            if (_st < 1) {
                _st = 1;
            }

            nubWrap.children().remove();
            wrap.children(".k_pagination_more").remove();
            if (_st !== 1 && _st !== opts.startpg) {
                $("<a style='line-height:" + h + "px;height:" + h + "px' class='k_pagination_more k_box_size'>...<div class='a_div'></div></a>").insertBefore(nubWrap).click(click).data("pg", "mp");
                first.removeClass("k_pagination_disabled");
                prev.removeClass("k_pagination_disabled");
            } else {
                first.addClass("k_pagination_disabled");
                prev.addClass("k_pagination_disabled");
            }
            if (last) {
                if (_st + opts.buttons >= opts.pageCount) {
                    last.addClass("k_pagination_disabled");
                    if (opts.page === opts.pageCount) {
                        next.addClass("k_pagination_disabled");
                    }
                } else {
                    last.removeClass("k_pagination_disabled");
                    next.removeClass("k_pagination_disabled");
                }
            }
            var help = opts.buttons;
            var aClickFn = function () {
                var $t = $(this);
                opts.page = $t.addClass("actived").data("pg");
                $t.siblings().removeClass("actived");
                if (opts.page === 1) {
                    first.addClass("k_pagination_disabled");
                    prev.addClass("k_pagination_disabled");
                } else {
                    first.removeClass("k_pagination_disabled");
                    prev.removeClass("k_pagination_disabled");
                }
                if (opts.page === opts.pageCount) {
                    last.addClass("k_pagination_disabled");
                    next.addClass("k_pagination_disabled");
                } else {
                    last.removeClass("k_pagination_disabled");
                    next.removeClass("k_pagination_disabled");
                }
                setTimeout(function () {
                    opts.onClick(opts.page, opts.pageSize, opts.startpg);
                }, 10);
            };
            while (help > 0 && _st <= opts.pageCount) {
                var $a = $("<a style='line-height:" + h + "px;height:" + h + "px' class='k_box_size k_pg_number'>" + _st + "<div class='a_div'></div></a>").appendTo(nubWrap).data("pg", _st);
                if (_st === opts.page) {
                    $a.addClass("actived");
                }
                $a.click(aClickFn);
                _st++;
                help--;
            }
            if (_st < opts.pageCount) {
                var $tmp = $("<a style='line-height:" + h + "px;height:" + h + "px' class='k_pagination_more k_box_size'>...<div class='a_div'></div></a>").insertAfter(nubWrap).click(click).data("pg", "mn");
            }
            if (opts.position === "center") {
                var w = 0;
                wrap.children().each(function () {
                    var $t = $(this);
                    w = w + $t.outerWidth() + 3;
                });
                wrap.width(w);
            }
        }
        createNum(opts.startpg);
        next = $("<a style='line-height:" + h + "px;height:" + h + "px' class='k_pagination_prev k_box_size'><i style='line-height:" + h + "px' class='fa fa-angle-right'></i><div class='a_div'></div></a>").appendTo(wrap).data("pg", "n");
        next.click(click);
        next.children("i").removeAttr("class").text($B.config.nextPage);
        if (opts.pageCount === 1) {
            next.addClass("k_pagination_disabled");
        }
        var lastBtn = $("<a style='line-height:" + h + "px;height:" + h + "px' class='k_pagination_last k_box_size'><i style='line-height:" + h + "px' class='fa fa-angle-double-right'></i><div class='a_div'></div></a>").appendTo(wrap).data("pg", "l");
        lastBtn.click(click);
        lastBtn.children("i").removeAttr("class").text($B.config.lastPage);
        last = lastBtn.hide();
        if (opts.startpg < opts.pageCount) {
            lastBtn.removeClass("k_pagination_disabled");
        } else {
            lastBtn.addClass("k_pagination_disabled");
        }
        var $sp = $("<span class='k_pagination_input_wrap'>" + $B.config.go2page + "&nbsp<input type='text'/>&nbsp" + $B.config.go2pageSuffix + "&nbsp<button class='k_pagination_input_button'>" + $B.config.buttonOkText + "</button></span>").appendTo(wrap);
        $sp.children("button").click(function () {
            var $t = $(this);
            var opts = $t.data("opts");
            var v = $t.siblings("input").val();
            if (v !== "") {
                try {
                    opts.startpg = parseInt(v);
                    if (opts.startpg > opts.pageCount || opts.startpg < 1) {
                        opts.startpg = 1;
                    }
                    opts.page = opts.startpg;
                    opts.onClick(opts.page, opts.pageSize, opts.startpg);
                } catch (e) { }
            }
        }).data("opts", opts);

        function createSum() {
            if (!opts.summary) {
                return;
            }
            wrap.children(".k_pagination_sum").remove();
            //"+opts.pageCount+"页
            var arr = ["<div class='k_pagination_sum'>" + $B.config.pageSum.replace("{total}", opts.total) + "<select>"];
            opts.pageList.push(opts.pageSize);
            var pageList = opts.pageList.unique();
            for (var i = 0, l = pageList.length; i < l; ++i) {
                var _tmp = "";
                if (pageList[i] === opts.pageSize) {
                    _tmp = "selected=selected";
                }
                arr.push("<option " + _tmp + " value='" + pageList[i] + "'>" + pageList[i] + "</option>");
            }
            arr.push("</select>" + $B.config.pageSumSuffix + "</div>");
            $(arr.join("")).prependTo(wrap).children("select").change(function () {
                var psize = parseInt($(this).val());
                opts.pageSize = psize;
                setTimeout(function () {
                    opts.onClick(1, opts.pageSize, 1);
                }, 10);
            });
        }
        createSum();
        if (opts.position === "center") {
            var w = 0;
            wrap.children().each(function () {
                var $t = $(this);
                w = w + $t.outerWidth() + 3;
            });
            wrap.width(w);
        }
        this.first = first;
        this.last = lastBtn;
        this.next = next;
        this.prev = prev;
        //根据当前页设置 按钮样式
        //最后一页
        if (opts.page === opts.pageCount) {
            if (opts.page > 1) {
                this.first.removeClass("k_pagination_disabled");
                this.prev.removeClass("k_pagination_disabled");
                this.last.addClass("k_pagination_disabled");
                this.next.addClass("k_pagination_disabled");
            } else {
                this.first.addClass("k_pagination_disabled");
                this.prev.addClass("k_pagination_disabled");
                this.last.addClass("k_pagination_disabled");
                this.next.addClass("k_pagination_disabled");
            }
        } else if (opts.page === 1) { //第一页
            if (opts.page < opts.pageCount) {
                this.first.addClass("k_pagination_disabled");
                this.prev.addClass("k_pagination_disabled");
                this.last.removeClass("k_pagination_disabled");
                this.next.removeClass("k_pagination_disabled");
            } else {
                this.first.addClass("k_pagination_disabled");
                this.prev.addClass("k_pagination_disabled");
                this.last.addClass("k_pagination_disabled");
                this.next.addClass("k_pagination_disabled");
            }
        } else {
            this.first.removeClass("k_pagination_disabled");
            this.prev.removeClass("k_pagination_disabled");
            this.last.removeClass("k_pagination_disabled");
            this.next.removeClass("k_pagination_disabled");
        }
    }

    function Pagination(jqObj, opts) {
        $B.extend(this, Pagination);
        this.opts = $.extend({}, def, opts);
        this.jqObj = jqObj.addClass("k_pagination_wrap clearfix");
        this.jqObj.append("<div class='k_pagination_" + this.opts.position + "'></div>");
        if (opts.height) {
            var lineHeight = opts.height + "";
            if(lineHeight.indexOf("px") < 0){
                lineHeight = lineHeight + "px";
            }
            this.jqObj.height(opts.height).css("line-height" ,lineHeight );
        }
        _create.call(this);
    }
    Pagination.prototype = {
        constructor: Pagination,
        /***新分页工具栏
        *args={
            total:1,//总数量
         }
        ***/
        update: function (args) {
            this.opts.page = 1;
            this.opts.startpg = 1;
            $.extend(this.opts, args);
            this.opts.pageCount = Math.ceil(this.opts.total / this.opts.pageSize) || 1; //总页数
            if (this.opts.startpg >= this.opts.pageCount) {
                this.opts.startpg = 1;
            }
            var $re = this.jqObj.children().children(".k_pagination_fresh").data("isTrigger", true);
            $re.trigger("click");
            $re.data("isTrigger", false);
            if (this.opts.page !== 1) {
                this.first.removeClass("k_pagination_disabled");
                this.prev.removeClass("k_pagination_disabled");
            } else {
                this.first.addClass("k_pagination_disabled");
                this.prev.addClass("k_pagination_disabled");
            }
            if (this.opts.page === this.opts.pageCount) {
                this.last.addClass("k_pagination_disabled");
                this.next.addClass("k_pagination_disabled");
            } else {
                this.last.removeClass("k_pagination_disabled");
                this.next.removeClass("k_pagination_disabled");
            }
        },
        /**
         *获取当前页
         ****/
        getCurPage: function () {
            return this.opts.page;
        }
    };
    $B["Pagination"] = Pagination;
    return Pagination;
}));(function (global, factory) {
    if (typeof define === 'function' && define.amd  && !window["_all_in_"]) {
        define(['$B', 'toolbar', 'plugin'], function (_$B) {
            return factory(global, _$B);
        });
    } else {
        if(!global["$B"]){
            global["$B"] = {};
        }
        factory(global, global["$B"]);
    }
}(typeof window !== "undefined" ? window : this, function (window, $B) {
    var defaultOpts = {
        title: '', //标题
        iconCls: null, //图标class，font-awesome字体图标
        toolbar: null, //工具栏对象参考工具栏组件配置说明
        width: 'auto',
        height: 'auto',
        shadow: true, //是否需要阴影
        radius: true, //是否圆角
        header: true, //是否显示头部
        zIndex: 999999,
        content: null, //静态内容或者url地址
        url:'',//请求地址
        dataType: 'html', //当为url请求时，html/json/iframe
        draggable: false, //是否可以拖动
        moveProxy: false, //是否代理移动方式
        draggableHandler: 'header', //拖动触发焦点
        closeable: false, //是否关闭
        closeType: 'hide', //关闭类型 hide(隐藏，可重新show)/ destroy 直接从dom中删除
        expandable: false, //可左右收缩
        maxminable: false, //可变化小大
        collapseable: false, //上下收缩
        onResized: null, //function (pr) { },//大小变化事件
        onLoaded: null, //function () { },//加载后
        onClose: null, //关闭前
        onClosed: null, //function () { },//关闭后
        onExpanded: null, // function (pr) { },//左右收缩后
        onCollapsed: null, // function (pr) { }//上下收缩后
        onCreated: null //function($content,$header){} panel创建完成事件
    };
    var config = $B["config"];
    var iframeHtml = "<iframe  class='panel_content_ifr' frameborder='0' style='overflow:visible;height:100%;width:100%;display:block;vertical-align:top;'  src='' ></iframe>";
    var loadingHtml = "<div class='k_box_size' style='position:absolute;z-index:2147483600;width:100%;height:26px;top:2px;left:0;' class='loading'><div class='k_box_size' style='filter: alpha(opacity=50);-moz-opacity: 0.5;-khtml-opacity: 0.5;opacity: 0.5;position:absolute;top:0;left:0;width:100%;height:100%;z-index:2147483600;background:#03369B;'></div><div class='k_box_size' style='width:100%;height:100%;line-height:26px;padding-left:16px;position:absolute;width:100%;height:100%;z-index:2147483611;color:#fff;text-align:center;'><i style='color:#fff;font-size:16px;' class='fa animate-spin fa-spin6'></i><span style='padding-left:5px;font-weight:bold;color:#fff;'>" + $B.config.loading + "</span></div></div>";
 
    var footToolbarHtml = '<div class="k_panel_foot_toolbar k_box_size" ></div>';
    var contentHtml = '<div class="k_panel_content k_box_size" >{c}</div>';
    var headerIconHtml = '<div style="padding-right:1px;height:100%;" class="k_panel_header_icon menu_img btn"><i style="font-size:16px;line-height:1.5em;" class="fa {icon}">\u200B</i></div>';
    var headerHtml = '<div class="k_panel_header"><div class="k_panel_header_content"><h1>{title}</h1><div class="k_panel_header_toolbar k_box_size"></div></div></div>';

    function Panel(jqObj, opts) {
        $B.extend(this, Panel); //继承父类
        var _this = this,
            c = "",
            headerHeight = 0,
            headerTop = 0;
        this.jqObj = jqObj.addClass("k_panel_main k_box_size");
        this.opts = $.extend({}, defaultOpts, opts);
        if (this.opts.shadow) {
            this.jqObj.addClass("k_box_shadow");
        }
        if (this.opts.radius) {
            this.jqObj.addClass("k_box_radius");
        }
        if (this.opts.header) {
            this.$header = $(headerHtml.replace("{title}", this.opts.title)).appendTo(this.jqObj);
            headerHeight = _this.$header.outerHeight();
            var _c = this.$header.children();
            headerTop = (headerHeight - 20) / 2;
            _c.children(".k_panel_header_toolbar").css("padding-top", headerTop);
        }
        var isUrl = false;
        var isString = typeof this.opts.content === "string";
        if (isString) {
            isUrl = $B.isUrl(this.opts.content);
        }
        if (!isUrl) {
            if (isString) {
                c = this.opts.content;
            }
        }
        this.$body = $(contentHtml.replace('{c}', c)).appendTo(this.jqObj).css({
            "border-top": "solid #ccc " + headerHeight + "px"
        });
        if(this.opts.bodyCss){
            this.$body.css(this.opts.bodyCss);
        }
        if (!isString && !isUrl) {
            this.$body.append(this.opts.content);
        }
        //加入工具栏功能
        this.toolArray = [];
        var toolbar;
        if (typeof this.opts.createToolsFn === 'function') { //由外部创建工具栏
            toolbar = $(footToolbarHtml).appendTo(this.jqObj);
            this.opts.createToolsFn.call(toolbar, this.opts.toolbar);
        } else {
            if (this.opts.toolbar) {
                toolbar = $(footToolbarHtml).appendTo(this.jqObj);
                var toolbarOpts ;
                if($.isArray( this.opts.toolbar)){
                    toolbarOpts = {buttons:this.opts.toolbar,"align":"center"};
                }else{
                    toolbarOpts = this.opts.toolbar;
                }
                this.toolArray.push(new $B.Toolbar(toolbar, toolbarOpts));
            }
        }
        var size = {
            height: this.opts.height,
            width: this.opts.width
        };
        this.jqObj.outerWidth(this.opts.width).outerHeight(this.opts.height).data("src_size", size);
        if (this.opts.iconCls != null && this.opts.header) {
            $(headerIconHtml.replace("{icon}", this.opts.iconCls)).prependTo(this.$header.children('.k_panel_header_content'));
        }
        if (this.opts.header) {
            var $toolbar = this.$header.children('.k_panel_header_content').children(".k_panel_header_toolbar");
            if (this.opts.closeable) {
                $("<a class='k_panel_tool_icon k_panel_close btn'><i class='fa fa-cancel'></i></a>").appendTo($toolbar).click(function () {
                    if (_this.opts.closeType === "hide") {
                        _this.close();
                    } else {
                        _this.destroy();
                    }
                    return false;
                });
            }
            if (this.opts.expandable) { //可左右收缩
                var isFunc = typeof _this.opts.onExpanded === 'function';
                var _extend = function (p) {
                    var $_t = p.children();
                    _this.jqObj.removeClass("k_panel_expandable_bg");
                    _this.jqObj.animate({
                        "width": _this.jqObj.data("lsWidth")
                    }, 10, function () {
                        p.siblings().show();
                        p.parent().prevAll().show();
                        _this.$header.css("border-bottom-width", "1px");
                        $_t.removeClass("fa-right-open-1").addClass("fa-left-open-2");
                        _this.jqObj.css("cursor", "default").off("click").children("div:gt(0)").fadeIn(100);
                        if (isFunc) {
                            setTimeout(function () {
                                _this.opts.onExpanded('right');
                            }, 1);
                        }
                    });
                };
                $("<a class='k_panel_tool_icon k_panel_slide_left btn'><i class='fa fa-left-open-2'></i></a>").appendTo($toolbar).click(function () {
                    var p = $(this);
                    var $_t = p.children();
                    if ($_t.hasClass("fa-left-open-2")) {
                        _this.jqObj.children("div:gt(0)").fadeOut(100, function () {
                            p.siblings().hide();
                            p.parent().prevAll().hide();
                            _this.$header.css("border-bottom-width", "0px");
                            _this.jqObj.data("lsWidth", _this.jqObj.width());
                            _this.jqObj.animate({
                                "width": 25
                            }, 10, function () {
                                _this.jqObj.addClass("k_panel_expandable_bg");
                                if (isFunc) {
                                    setTimeout(function () {
                                        _this.opts.onExpanded('left');
                                    }, 1);
                                }
                            }).css("cursor", "pointer").on("click", function () {
                                _extend(p);
                            });
                            $_t.removeClass("fa-left-open-2").addClass("fa-right-open-1");
                        });
                    } else {
                        _extend(p);
                    }
                    return false;
                });
            }
            if (this.opts.maxminable) { //可变化小大
                var $a = $("<a class='k_panel_tool_icon k_panel_maxbtn'><i class='fa fa-resize-full'></i></a>").appendTo($toolbar).click(function () {
                    var $_t = $(this).children(),
                        flag, pr;
                    if ($_t.hasClass("fa-resize-full")) {
                        var $parent = _this.jqObj.parent();
                        var zIndex = _this.jqObj.css("z-index");
                        _this.jqObj.data("zIndex", zIndex);
                        _this.jqObj.css("z-index", _this.opts.zIndex);
                        var p_width = $parent.width();
                        var p_height = $parent.height();
                        pr = {
                            width: p_width,
                            height: p_height
                        };
                        if (_this.opts.draggable) {
                            pr["top"] = 0;
                            pr["left"] = 0;
                            _this.jqObj.data("src_pos", _this.jqObj.position());
                        }
                        _this.jqObj.animate(pr, 100);
                        $_t.removeClass("fa-resize-full").addClass("fa-resize-small");
                        flag = "max";
                    } else {
                        var src_size = _this.jqObj.data("src_size");
                        pr = {
                            width: src_size.width,
                            height: src_size.height
                        };
                        if (_this.opts.draggable) {
                            var src_pos = _this.jqObj.data("src_pos");
                            pr["top"] = src_pos.top;
                            pr["left"] = src_pos.left;
                        }
                        _this.jqObj.css("z-index", _this.jqObj.data("zIndex"));
                        _this.jqObj.animate(pr, 100);
                        $_t.removeClass("fa-resize-small").addClass("fa-resize-full");
                        flag = "min";
                    }
                    if (typeof _this.opts.onResized === 'function') {
                        _this.opts.onResized(flag);
                    }
                    return false;
                });
                //加入双击功能
                if (this.$header) {
                    this.$header.data("_ck", $a);
                    this.$header.click(function () {
                        return false;
                    }).dblclick(function () {
                        $(this).data("_ck").trigger("click");
                        return false;
                    });
                }
            }
            if (this.opts.collapseable) { //上下收缩
                $("<a class='k_panel_tool_icon  btn'><i class='fa fa-down-open-2'></i></a>").appendTo($toolbar).click(function () {
                    var $_t = $(this).children();
                    var f;
                    if ($_t.hasClass("fa-down-open-2")) {
                        _this.jqObj.children("div:gt(0)").fadeOut(100, function () {
                            _this.jqObj.data("lsHeight", _this.jqObj.height());
                            _this.jqObj.animate({
                                "height": headerHeight
                            }, 200);
                            $_t.removeClass("fa-down-open-2").addClass("fa fa-up-open-2");
                        });
                        f = "down";
                    } else {
                        _this.jqObj.animate({
                            "height": _this.jqObj.data("lsHeight")
                        }, 100, function () {
                            _this.jqObj.children("div:gt(0)").fadeIn(100);
                            $_t.removeClass("fa-up-open-2").addClass("fa-down-open-2");
                        });
                        f = "up";
                    }
                    if (typeof _this.opts.onCollapsed === "function") {
                        setTimeout(function () {
                            _this.opts.onCollapsed(f);
                        }, 1);
                    }
                    return false;
                });
            }
        }
        if (this.opts.draggable) {
            var dragOpt = {
                isProxy: this.opts.moveProxy,
                onDragReady: this.opts.onDragReady, //鼠标按下时候准备拖动前，返回true则往下执行，返回false则停止
                onStartDrag: this.opts.onStartDrag, //开始拖动事件
                onDrag: this.opts.onDrag, //拖动中事件
                onStopDrag: this.opts.onStopDrag //拖动结束事件
            };
            if (dragOpt.isProxy && this.opts.header) {
                dragOpt["onMouseDown"] = function (state, e) {
                    if (e.target.nodeName === "I") {
                        return false;
                    }
                };
            }
            if (this.opts.draggableHandler === 'header' && this.opts.header) {
                dragOpt["handler"] = this.$header;
            }
            jqObj.draggable(dragOpt);
        }
        if (toolbar) {
            var _h = toolbar.outerHeight();
            _this.$body.css({
                "border-bottom-width": _h + "px",
                "border-bottom-style": "solid",
                "border-bottom-color": "#ffffff"
            });
        }
        if (typeof this.opts.onCreated === 'function') {
            this.opts.onCreated.call(this.jqObj, this.$body, this.$header);
        }
        _this.$body.css("overflow", "auto");
        if ($B.isUrl(this.opts.content) || this.opts.url !== "") {
            var _url =  this.opts.url;
            if($B.isUrl(this.opts.content)){
                _url = this.opts.content;
            }
            this.load({
                url: _url,
                dataType: this.opts.dataType
            });
        }
    }
    Panel.prototype = {
        constructor: Panel,
        /**用于加载数据
         *args={
            url: null,//url地址
            dataType:'html/json/iframe'
        }**/
        load: function (args) {
            var url = this.opts.url;
            if($B.isUrl(this.opts.content)){
                url = this.opts.content;
            }
            var dataType = this.opts.dataType;
            var _this = this;
            if (args) {
                url = args.url;
                dataType = args.dataType;
            }
            var isFun = typeof this.opts.onLoaded === 'function';           
            if(url.indexOf("?") > 0){
                url = url + "&_t_="+$B.generateMixed(5);
            }else{
                url = url + "?_t_="+$B.generateMixed(5);
            }
            this.url = url;
            var loading = $(loadingHtml);
            loading.appendTo(_this.$body);
            setTimeout(function () {               
                if (dataType === "html") {                   
                    $B.htmlLoad({
                        target: _this.$body,
                        url: url,
                        onLoaded: function () {
                            loading.fadeOut(function(){
                                $(this).remove();
                            });
                            if (isFun) {
                                _this.opts.onLoaded.call(_this.$body,{});
                            }
                            $B.bindTextClear(_this.$body);
                        }
                    });
                } else if (dataType === "json") {                   
                    $B.request({
                        dataType: 'json',
                        url: url,
                        ok: function (message, data) {
                            if (isFun) {
                                _this.opts.onLoaded.call(_this.$body, data);
                            }
                        },
                        final: function (res) {
                            loading.fadeOut(function(){
                                $(this).remove();
                            });
                        }
                    });
                } else {
                    if (!_this.iframe) {                        
                        _this.iframe = $(iframeHtml);
                        _this.iframe.on("load", function (e) {
                            var _t = $(this);
                            var url = _t.attr("src");
                            if (url !== "") {                         
                                if (isFun) {
                                    _this.opts.onLoaded.call(_this.$body,{});
                                }
                                try {
                                    loading.fadeOut(function(){
                                        $(this).remove();
                                    });
                                } catch (ex) {
                                    
                                }
                                var ua = window.navigator.userAgent;
                                var isFirefox = ua.indexOf("Firefox") !== -1;
                                if (isFirefox) {
                                    try {
                                        $(this.contentDocument.body).find("a").each(function () {
                                            var $a = $(this);
                                            if ($a.attr("href").toLowerCase().indexOf("javascript") > -1) {
                                                $a.attr("href", "#");
                                            }
                                        });
                                    } catch (ex) {}
                                }
                            }
                        });
                    }    
                    _this.iframe[0].src = url;   
                    _this.iframe.appendTo(_this.$body) ;
                }
            }, 10);
        },
        /**
         * 更新静态内容 content
         * ***/
        updateContent: function (content) {
            this.$body.html(content);
        },
        /**
         * args={title:'标题',iconCls:'图标样式'}/args=title
         ***/
        setTitle: function (args) {
            if (!this.opts.header) {
                return;
            }
            if (typeof args === 'string') {
                this.$header.children().children("h1").html(args);
            } else {
                if (args.title) {
                    this.$header.children().children("h1").html(args.title);
                }
                if (args.iconCls) {
                    var icon = this.$header.children().children(".k_panel_header_icon").find("i.fa");
                    icon.attr("class","fa "+args.iconCls);
                }
            }
        },
        /**关闭
         * ifForce:是否强制关闭，强制则忽略onClose的返回
         * **/
        close: function (isForce) {
            if(!this.opts){
                return;
            }
            $("body").children("#k_text_clear_btn").hide();
            if(this.opts.closeType === "destroy"){
                this.destroy();
                return;
            }
            var _this = this;
            var goClose = true;
            if (typeof _this.opts.onClose === 'function') {
                goClose = _this.opts.onClose();
            }
            if (isForce || goClose) {
                var fn = function () {
                    // var _scrollId = _this.$body.id;                    
                    // var $b = $("body");
                    // $b.children("#" + _scrollId).remove();
                    // $b.children("#" + _scrollId + '-hr').remove();
                    _this._invokeClosedFn();
                };
                if(_this.opts.position){
                    if(_this.opts.position === "bottom"){
                        this.jqObj.fadeOut(200, fn);
                    }else{
                        this.jqObj.animate({top:-2000},500,fn);
                    }
                }else{
                    this.jqObj.fadeOut(200, fn);
                }
            }
        },
        /**显示**/
        show: function () {
            if (this.jqObj) {
                this.jqObj.fadeIn(200, function () {});
            }
        },
        _invokeClosedFn:function(){
            /*******如果是html数据格式，销毁窗口内的弹窗********/           
            if(this.opts.dataType !== "iframe"){
                var isHide = this.opts.closeType === "hide";
                /***颜色控件 k_color_picker_cls***/
                this.$body.find(".k_color_picker_cls").each(function(){
                    var $t = $(this);
                    var obj = $t.data("picker");
                    if(obj && obj.destroy){
                        if(isHide){
                            obj.hide();
                        }else{
                            obj.destroy();
                        }                        
                    }
                });
                /***时间控件 k_calendar_input***/
                this.$body.find(".k_calendar_input").each(function(){
                    var $t = $(this);
                    var obj = $t.data("calender");
                    if(obj && obj.destroy){
                        if(isHide){
                            obj.hide();
                        }else{
                            obj.destroy();
                        }                       
                    }
                });
                /******combox k_combox_input*********/
                this.$body.find(".k_combox_input").each(function(){
                    var $t = $(this);
                    var obj = $t.data("combox");
                    if(obj && obj.destroy){
                        if(isHide){
                            obj.hide();
                        }else{
                            obj.destroy();
                        }
                    }
                });
            }
            this.jqObj.hide();
            var _this = this;
            if (typeof _this.opts.onClosed === 'function') {
                try {
                    _this.opts.onClosed.call(this.jqObj);
                } catch (e) {
                    _this.error(e);
                }
            }
        },
        /**
         * 销毁
         * **/
        destroy: function () {
            var _this = this;
            for (var i = 0, len = this.toolArray.length; i < len; ++i) {
                this.toolArray[i].destroy();
            }
            if (typeof _this.opts.onClose === 'function') {
                _this.opts.onClose();
            }
            if (this.jqObj.css("display") === "block") {
                var f = function () {                   
                    _this._invokeClosedFn();
                    _this.jqObj.remove();
                    _this.super.destroy.call(_this);
                };
                this.jqObj.fadeOut("fast", f);
            } else {
                _this._invokeClosedFn();
                this.jqObj.remove();
                this.super.destroy.call(this);
            }
        },
        /*重设大小
         * args={width:,height:}
         * **/
        resize: function (args, callBack) {
            var rs = {},
                _this = this;
            if (args.width) {
                rs["width"] = args.width;
            }
            if (args.height) {
                rs["height"] = args.height;
            }
            this.jqObj.css(rs);
            if (typeof _this.opts.onResized === 'function') {
                setTimeout(function(){
                    _this.opts.onResized();
                },10);                
            }
        },
        /***获取大小***/
        getSize: function () {
            return {
                width: this.jqObj.outerWidth(),
                height: this.jqObj.outerHeight()
            };
        },
        /**获取iframe**/
        getIfr: function () {
            if (this.opts.dataType !== 'iframe') {
                return;
            }
            return this.$body.children("iframe")[0];
        },
        hide: function () {
            this.close(true);
        },
        setAttr: function (attr) {
            this.jqObj.attr(attr);
        }
    };
    $B["Panel"] = Panel;
    return Panel;
}));/**下拉列表***/
function _createDropDownListFn($) {
    /***
     * jquery下拉列表
     * options = [
     * {
     *     text:'选项1',
     *     icon:'font-icon',
     *     click:function(){
     *          
     *     } 
     * },{
     * }]
     * ***/
    $.fn.dropDownList = function (options) {
        var $body = $(window.document.body).css("position", "relative");
        var dropDownWrap;
        var hideTimer;
        function makelist() {
            var ofs = this.offset();
            var curnId = this.data("_droplist_id");
            dropDownWrap = $body.children("#" + curnId);
            if (dropDownWrap.length === 0) {
                dropDownWrap = $("<div id='" + curnId + "' style='height:auto;position:absolute;z-index:2147483647;top:-10000px;display:none;' class='k_context_menu_container k_box_shadow k_box_radius'></div>");
                var it, $it;
                for (var i = 0, len = options.length; i < len; ++i) {
                    it = options[i];
                    $it = $('<div class="k_context_menu_item_cls"><span class="k_toolbar_img_black k_context_menu_item_ioc btn"><i class="fa ' + it.icon + '"></i></span><span class="k_context_menu_item_txt">' + it.text + '</span></div>');
                    $it.click(it.click).appendTo(dropDownWrap);
                }
                dropDownWrap.appendTo($body);
                dropDownWrap.on("mouseenter", function () {
                    clearTimeout(hideTimer);
                }).on("mouseleave", function () {
                    hidelist();
                });
            }
            var pos = { top: ofs.top + this.outerHeight(), left: ofs.left };
            dropDownWrap.css(pos).show();
        }
        function hidelist() {
            clearTimeout(hideTimer);
            hideTimer = setTimeout(function () {
                dropDownWrap.hide();
            }, 1000);
        }

        return this.each(function () {
            var $t = $(this);
            //console.log("display = " + $t.css("display"));
            var wrap = $("<div style='display: inline-block'></div>");
            wrap = $t.wrap(wrap).parent();
            var height = wrap.height();
            var color = $t.css("color");
            wrap.append("<i class='fa fa-down-dir' style='line-height:" + height + "px;color:" + color + ";font-size:1.2em;padding-left:5px;'></i>");
            var id = $B.getUUID();
            wrap.data("_droplist_id", id);
            wrap.css("cursor", "pointer").mouseenter(function () {
                makelist.call($(this));
            }).mouseleave(function () {
                hidelist.call($(this));
            });
        });
    };
}


/***提交服务器事件封装,集合request请求对当前提交按钮做防止二次提交处理****/
function _makeJquerySubmitEevent($) {
    $.fn.submit = function (event) {
        return this.each(function () {
            $(this).click(function () {
                var $t = $(this);
                if (!window["_submit_queues"]) {
                    window["_submit_queues"] = [];
                    setInterval(function () {
                        var newQ = [];
                        var now = new Date();
                        for (var i = 0, len = window["_submit_queues"].length; i < len; ++i) {
                            var q = window["_submit_queues"][i];
                            if ((now - q.date) < 2000) {//大于三秒则剔除
                                newQ.push(q);
                            } else {
                                q.btn = undefined;
                                q.date = undefined;
                            }
                        }
                        window["_submit_queues"] = newQ;
                    }, 3000);
                }
                window["_submit_queues"].push({
                    btn: $t,
                    date: new Date()
                });
                event.call($t);
            });
        });
    };
}

/****拖动实现****/
(function (global, factory) {
    if (typeof define === 'function' && define.amd  && !window["_all_in_"]) {
        define(['jquery'], function ($) {
            return factory(global, $);
        });
    } else {
        factory(global, $);
    }
}(typeof window !== "undefined" ? window : this, function (window, $) {
    _createDropDownListFn($);
    _makeJquerySubmitEevent($);

    /****以下为拖动jqueyr插件****/
    // try{
    //     // _moz_abspos
    //     document.designMode = "on";
    //     document.execCommand('enableObjectResizing', false, 'false');
    // }catch(ex){
    // } 
    var draggableDefaults = {
        nameSpace: 'draggable', //命名空间，一个对象可以绑定多种拖动实现
        which: undefined, //鼠标键码，是否左键,右键 才能触发拖动，默认左右键均可
        defaultZindex: 999999, //当z-index为auto时采用的层级数值
        holdTime: undefined, //按下鼠标多少毫秒才拖动，默认不设置立即可拖动
        isProxy: false, //是否产生一个空代理进行拖动
        disabled: false, //是否禁用拖动
        handler: undefined, //触发拖动的对象，默认是对象本身
        cursor: 'move', //鼠标样式
        axis: undefined, // v垂直方 h水平，默认全向           
        onDragReady: undefined, //鼠标按下时候准备拖动前，返回true则往下执行，返回false则停止
        onStartDrag: undefined, //开始拖动事件
        onDrag: undefined, //拖动中事件
        onStopDrag: undefined, //拖动结束事件
        onMouseUp: undefined //当没有发生拖动，鼠标放开时候调用
    };
    //实现jquery对象可拖动       
    var $doc = $(window.document);
    var $body;
    function _getBody() {
        if (!$body) {
            $body = $(window.document.body).css("position", "relative");
        }
        return $body;
    }
    /***
     * 根据鼠标计算位置
     * ****/
    function _compute(e) {
        var state = e.data,
            data = state._data,
            opts = state.options;
        //拖动后的 = 原先+拖动位移
        var leftOffset = e.pageX - data.startX,
            topOffset = e.pageY - data.startY;
        if (opts.axis === 'v') { //如果是垂直，则只改top
            leftOffset = 0;
        } else if (opts.axis === 'h') { //如果是水平拖动 则只改left
            topOffset = 0;
        }
        var left = data.startLeft + leftOffset,
            top = data.startTop + topOffset;
        data.leftOffset = leftOffset;
        data.topOffset = topOffset;
        data.oldLeft = data.left;
        data.oldTop = data.top;
        data.left = left;
        data.top = top;
        var apply = true;
        if (state["onDragFn"]) {
            var args = {
                state: state,
                which: opts.which
            };
            var res = opts.onDrag(args);
            if (typeof res !== 'undefined') {
                apply = res;
            }
        }
        data["apply"] = apply;
    }
    //移动事件 hasCallStartFn
    function _docMove(e) {
        //console.log("doc move............");
        var state = e.data;
        var opts = state.options;
        var data = state._data;
        if (!state["hasCallStartFn"]) {
            //处理没有发生鼠标移动但是_docMove被触发的情况！！
            var leftOffset = e.pageX - data.startX,
                topOffset = e.pageY - data.startY;
            if (leftOffset === 0 && topOffset === 0) {
                console.log("过滤没有发生实际移动的 _docMove");
                return;
            }
            state["hasCallStartFn"] = true;
            state.target.data("_mvdata", data);
            if (state.callStartDragFn) {
                //提取拖动目标的zIndex 2147483647
                var zIndex = state.movingTarget.css("z-index");
                if (zIndex === "auto") {
                    zIndex = opts.defaultZindex;
                }
                state["zIndex"] = zIndex;
                state.movingTarget.css("z-index", 2147483647);
                try {
                    opts.onStartDrag({
                        state: state
                    });
                } catch (ex) {
                    if (console.error) {
                        console.error("onStartDrag error " + ex);
                    } else {
                        console.log("onStartDrag error " + ex);
                    }
                }
            }
        }
        _compute(e);
        if (data["apply"] && state.movingTarget) {
            var css = {
                left: data.left + data.fixLeft,
                top: data.top + data.fixTop,
                cursor: state.options.cursor
            };
            state.movingTarget.css(css);
        }
        if (typeof opts.notClearRange === "undefined") {
            //先清除document中的选择区域
            if (document.selection) {
                document.selection.empty();
            } else if (window.getSelection) {
                window.getSelection().removeAllRanges();
            }
        }
    }
    /***
     * 应该domcument监听鼠标放开事件
     * ***/
    function _docUp(e) {
        //console.log("doc up............");
        var state = e.data,
            data = state._data,
            opts = state.options,
            nameSpace = opts.nameSpace,
            target = state.target;
        $doc.off('.' + nameSpace);
        target.css('cursor', data.srcsor);
        if (opts.isProxy) { //代理移动方式,则需要更新目标位置
            state["movingTarget"].remove();
            var css = {
                left: data.left,
                top: data.top
            };
            target.css(css);
        }
        var onStopDrag = opts.onStopDrag;
        if (typeof onStopDrag === "function" && state["hasCallStartFn"]) {
            onStopDrag({
                state: state
            });
        }
        state.target.removeData("_mvdata");
        if (state["hasCallStartFn"]) {
            var zIndex = state["zIndex"];
            state.movingTarget.css("z-index", zIndex);
        } else {
            if (opts.onMouseUp) {
                opts.onMouseUp({
                    state: state
                });
            }
        }
        data.leftOffset = 0;
        data.topOffset = 0;
        _getBody().css("cursor", "default");
    }
    //监听document鼠标按下事件
    function _docDown(e) {
        //console.log("_docDown............");
        var state = e.data,
            opts = state.options;
        var movingTarget = state.target;
        if (opts.isProxy) {
            var ofs = state.target.offset(),
                w = state.target.outerWidth(),
                h = state.target.outerHeight();
            movingTarget = $("<div style='cursor:" + opts.cursor + ";position:absolute;width:" + w + "px;height:" + h + "px;top:" + ofs.top + "px;left:" + ofs.left + "px' class='k_draggable_proxy'></div>").appendTo(_getBody());
        }
        if (typeof opts.onDrag === "function") {
            state["onDragFn"] = true;
        }
        state["movingTarget"] = movingTarget;
        _getBody().css("cursor", opts.cursor);
    }
    /***
     * 鼠标放开
     ****/
    function onMouseUp(e) {
        var dragtimer = $(this).data("dragtimer");
        if (dragtimer) {
            clearTimeout(dragtimer);
            var state = e.data;
            state.target.removeData("_mvdata");
            if (!state["hasCallStartFn"]) { //如果没有发生拖动
                var opts = state.options;
                if (opts.onMouseUp) {
                    opts.onMouseUp({
                        state: state
                    });
                }
            }
        }
    }
    /**
     * args应对编程trigger触发的鼠标事件
     * e参数中不存在pageX、pageY的情况
     * **/
    function onMouseDown(e, args) {
        if (args && !e["pageX"]) {
            e["pageX"] = args.pageX;
            e["pageY"] = args.pageY;
            e["which"] = args.which;
        }
        var state = e.data;
        var $t = state.target;
        var options = state.options;
        if (!options.which || options.which === e.which) {
            if (!options.disabled) {
                var go = true;
                if (typeof options.onDragReady === 'function') {
                    go = options.onDragReady.call($t, state);
                }
                if (go) {
                    var offset = $t.position();
                    //如果有css transform旋转，需要计算出 修正的偏移量    
                    var ofs = $B.getAnglePositionOffset($t);
                    var fixTop = ofs.fixTop;
                    var fixLeft = ofs.fixLeft;
                    var parent = $t.parent();
                    var scrollLeft = 0, scrollTop = 0;
                    if (parent[0] !== document.body) {
                        scrollLeft = parent.scrollLeft();
                        scrollTop = parent.scrollTop();
                    }
                    /**2019-05-21 补充 scroll量***/
                    $t.css({
                        "position": "absolute",
                        "top": offset.top + fixTop  + scrollTop,
                        "left": offset.left + fixLeft + scrollLeft
                    });
                    var srcsor = $t.css("cursor");
                    if (!srcsor) {
                        srcsor = 'default';
                    }
                    var position = $t.position();
                    //封装拖动数据data对象，记录width,height,pageX,pageY,left 和top 等拖动信息
                    var data = {
                        startLeft: position.left + scrollLeft, //开始的位置信息	
                        startTop: position.top + scrollTop, //开始的位置信息	
                        scrollLeft: scrollLeft,
                        scrollTop: scrollTop,
                        left: position.left + scrollLeft, //当前left位置信息	
                        top: position.top + scrollTop, //当前top位置信息
                        oldLeft: undefined, //旧的left位置 
                        oldTop: undefined, //旧的top位置	
                        startX: e.pageX, //鼠标点击时的x坐标
                        startY: e.pageY, //鼠标点击时的y坐标
                        width: $t.outerWidth(),
                        height: $t.outerHeight(),
                        fixTop: fixTop,
                        fixLeft: fixLeft,
                        srcsor: srcsor, //原来的鼠标样式
                        leftOffset: 0, //鼠标left偏移
                        topOffset: 0 //鼠标top偏移
                    };
                    state["hasCallStartFn"] = false; //是否已经调用了onStartDrag   
                    state["_data"] = data;
                    state["parent"] = parent; //拖动对象的父dom
                    state["callStartDragFn"] = typeof options.onStartDrag === "function";
                    var nameSpace = options.nameSpace;
                    if (typeof options.holdTime !== 'undefined') {
                        var _this = $(this);
                        var timer = setTimeout(function () {
                            $t.css("cursor", state.options.cursor);
                            //往document上绑定鼠标移到监听 
                            _docDown({
                                data: state
                            });
                            $doc.on('mousemove.' + nameSpace, state, _docMove);
                            $doc.on('mouseup.' + nameSpace, state, _docUp);
                        }, options.holdTime);
                        _this.data("dragtimer", timer);
                    } else {
                        $t.css("cursor", state.options.cursor);
                        //往document上绑定鼠标监听 
                        $doc.on('mousedown.' + nameSpace, state, _docDown);
                        $doc.on('mousemove.' + nameSpace, state, _docMove);
                        $doc.on('mouseup.' + nameSpace, state, _docUp);
                    }
                }
            }
        }
    }
    /****
     * 构造函数
     * options：defaults参数
     * *****/
    $.fn.draggable = function (options) {
        var nameSpace = "draggable";
        if (typeof options === 'string') {
            if (arguments.length > 1) {
                nameSpace = arguments[1];
            }
            switch (options) {
                case 'enable': //启用拖动
                    return this.each(function () {
                        var $t = $(this);
                        var state = $t.data(nameSpace);
                        if (state) {
                            state.options.disabled = false;
                        }
                        $t.css("cursor", state.options.cursor);
                    });
                case 'disable': //禁用拖动
                    return this.each(function () {
                        var $t = $(this);
                        var state = $t.data(nameSpace);
                        if (state) {
                            state.options.disabled = true;
                        }
                        $t.css("cursor", "default");
                    });
                case 'unbind': //解除拖动
                    return this.each(function () {
                        var $t = $(this);
                        var state = $t.data(nameSpace);
                        state.handler.off('.' + nameSpace);
                        $t.removeData(nameSpace);
                        delete state.handler;
                        delete state.target;
                        delete state.options;
                        delete state.parent;
                    });
                default:
                    throw new Error("不支持:" + options);
            }
        }
        var opts = $.extend({}, draggableDefaults, options);
        if (opts.nameSpace) {
            nameSpace = opts.nameSpace; //默认的命名空间
        }
        return this.each(function () {
            var $t = $(this);
            var handler = $t; //handler是实际触发拖动的对象
            if (opts.handler) {
                handler = (typeof opts.handler === 'string' ? $t.find(opts.handler) : opts.handler);
                handler.css("cursor", options.cursor);
            }
            //存在则先解除已经绑定的拖动
            var state = $t.data(nameSpace);
            if (state) {
                state.handler.off('.' + nameSpace);
                delete state["handler"];
                delete state["target"];
                delete state["parent"];
                delete state["options"];
                delete state["_data"];
            }
            state = {
                handler: handler,
                target: $t,
                options: opts
            };
            $t.data(nameSpace, state);
            //注册事件 draggable 为命名空间
            handler.on('mousedown.' + nameSpace, state, onMouseDown);
            if (typeof opts.holdTime !== 'undefined') {
                handler.on('mouseup.' + nameSpace, state, onMouseUp);
            }
        });
    };
    $.fn.loading = function (message) {
        var loadingTip = $B.config.loading;
        if (message) {
            loadingTip = message;
        }
        var loadingHtml = "<div style='width:auto;z-index:2147483647;' class='k_datagrid_loading'><i class='fa fa-cog fa-spin fa-1.6x fa-fw margin-bottom'></i>" + loadingTip + "</div>";
        return this.each(function () {
            var $t = $(this);
            $t.html(loadingHtml);
        });
    };

    /****以下为jquey滚动条插件****   
     * 全局单列，鼠标hover上目标才显示scrollbar
     * @Author: kevin.huang 
     * @Date:  2019-01-06 12:00:01
     * Copyright (c): kevin.huang Released under MIT License
     * ****/
    var scrollDefaults = {
        slider: {
            "background-color": '#6F6F6F',
            "border-radius": "8px"
        },
        size:'6px',
        hightColor: "#05213B",
        bar: {
            "background-color": "#e4e4e4",
            "border-radius": "8px",
            "opacity": 0.5
        },
        setPadding:true,
        display: 'show',//显示方式，auto 自动显示，隐藏，show:固定显示
        wheelStep: 60,
        axis: 'xy', //x,y,xy
        checkItv: 0,//是否开启自动检查，0表示不开启，其他值 为毫秒数，表示checkItv毫秒检测一次内容是否发生变化并自动更正滚动条位置
        minHeight: 50,
        minWidth: 50
    };
    function scrollbar($el, opts) {
        this.opts = opts;
        this.yscroll = opts.yscroll;
        this.xscroll = opts.xscroll;
        this.$doc = $(document);
        this.jqObj = $el;
        this.$scrollWrap = this.jqObj.children(".k_scroll_wrap");
        this.scrollHeight = this.$scrollWrap[0].scrollHeight; //只有内容发生变化后，才会触发更新
        this.scrollWidth = this.$scrollWrap[0].scrollWidth; //只有内容发生变化后，才会触发更新
        if (this.yscroll) {            
            this.$vbar = this.jqObj.children(".k_scroll_v_bar").css(this.opts.bar);
            this.$vbtn = this.$vbar.children("div").css(this.opts.slider);
            this._initVbtnHeight();
            this._initVbtnDragEvent();
            this._bindMousewheel();
            this._hightLine(this.$vbtn);
        }
        if (this.xscroll) {
            this.$Hbar = this.jqObj.children(".k_scroll_h_bar").css(this.opts.bar);
            this.$Hbtn = this.$Hbar.children("div").css(this.opts.slider);
            this._hightLine(this.$Hbtn);
            this._initHbtnWidth();
            this._initHbtnDragEvent();
        }
        this._bindContentScrollListner();
        var _this = this;
        if (this.opts.checkItv > 0 && (this.yscroll || this.xscroll)) {
            this.ivt = setInterval(function () {//每秒钟检查一次滚动内容高度、宽度是否发生了变化
                if (_this.jqObj.parent().length === 0) {
                    _this.destroy();
                } else {
                    _this.resetSliderPosition();
                }
            }, this.opts.checkItv);
        }
        this.showOrHideVbtn();
        this.showOrHideHbtn();
        if (this.opts.display === "auto" && (this.yscroll || this.xscroll)) {//开启自动隐藏功能
            this.fadeOut();
            this.jqObj.on({
                "mouseenter": function () {
                    _this.showOrHideVbtn();
                    _this.showOrHideHbtn();
                    _this.autoHide = false;
                },
                "mouseleave": function () {
                    if (!_this.scrolling  ) {
                        _this.fadeOut();
                    } else {
                        _this.autoHide = true;
                    }
                }
            });
        }
        $(window).resize(function(){
            _this.resetSliderPosByTimer();
        });
    }
    scrollbar.prototype = {
        _initHbtnWidth:function(){
            var scrollWidth = this.scrollWidth;
            var rate = this.$scrollWrap.width() / scrollWidth;
            var barWidth = this.$Hbar.width();
            var halft = barWidth / 2;
            var sliderWidth = rate * barWidth;
            if (sliderWidth < this.opts.minWidth) {
                sliderWidth = this.opts.minWidth;
            }else if(sliderWidth >  halft){
                sliderWidth = halft;
            }
            this.$Hbtn.css('width', sliderWidth);
        },
        _initHbtnDragEvent:function(){
            var _this = this;
            var slider = this.$Hbtn;
            var doc = this.$doc,
                dragStartPostion,
                dragStartScrollPostion,
                dragContBarRate;//滚动比例
            function moveHandler(e) {
                e.preventDefault();
                if (dragStartPostion == null) {
                    return;
                }
                if(!_this.$Hbtn.data("ishl")){
                    _this.$Hbtn.css({ "background-color": _this.opts.hightColor}).data("ishl",true);
                    _this.$Hbar.css({"opacity": 0.9});
                }              
                _this.scrollLeft(dragStartScrollPostion + (e.pageX - dragStartPostion) * dragContBarRate);
            }
            slider.on('mousedown', function (e) {
                e.preventDefault();
                dragStartPostion = e.pageX;
                dragStartScrollPostion = _this.$scrollWrap[0].scrollLeft;
                var scrollLen = _this.getMaxScrollLeftPosition();           
                dragContBarRate = scrollLen  / _this.getMaxHbtnPosition();
                _this.scrolling = true;
                doc.on('mousemove.kscroll', moveHandler).on('mouseup.kscroll', function () {
                    doc.off('.kscroll');
                    _this.maxScrollLeft = undefined;
                    _this.maxHbtnPosition = undefined;
                    _this.$Hbtn.css({ "background-color": _this.opts.slider["background-color"] }).removeData("ishl");
                    _this.$Hbar.css({"opacity": _this.opts.bar["opacity"]});
                    _this.scrolling = false;
                    if (_this.autoHide) {
                        _this.fadeOut();
                    }
                });
            });
        },
        getMaxScrollLeftPosition:function(){
            if (typeof this.maxScrollLeft === "undefined") {
                var w = this.$scrollWrap.width();
                this.maxScrollLeft = Math.max(w, this.scrollWidth) - w;
            }
            return this.maxScrollLeft;
        },
        getMaxHbtnPosition:function(){
            if (typeof this.maxHbtnPosition === "undefined") {
                this.maxHbtnPosition = this.$Hbar.width() - this.$Hbtn.width();
            }
            return this.maxHbtnPosition;
        },
        getHbtnPosition:function(){
            var maxSliderPosition = this.getMaxHbtnPosition();
            return Math.min(maxSliderPosition, maxSliderPosition * this.$scrollWrap[0].scrollLeft / this.getMaxScrollLeftPosition());
        },
        showOrHideHbtn: function (scrollWidth) {
            if (this.xscroll) {
                if (!scrollWidth) {
                    scrollWidth = this.scrollWidth;
                }
                var width = this.$scrollWrap.width();
                if (scrollWidth <= width) {
                    this.$Hbar.hide();
                    this.jqObj.css("padding-bottom", 0);
                } else {
                    this.$Hbar.show();
                    this.jqObj.css("padding-bottom", this.$Hbar.height() + "px");
                }
            }
        },
        scrollLeft:function(v){   
            this.$scrollWrap.scrollLeft(v);   
            //this.$scrollWrap.animate({scrollLeft:v},50);
        },
        /**y轴滚动条***/
        _initVbtnHeight: function () {
            var scrollHeight = this.scrollHeight;
            var barHeight = this.$vbar.height();
            var halft = barHeight / 2;
            var rate = this.$scrollWrap.height() / scrollHeight;
            var sliderHeight = rate * barHeight;
            if (sliderHeight < this.opts.minHeight) {
                sliderHeight = this.opts.minHeight;
            }else if(sliderHeight > halft){
                sliderHeight = halft;
            }
            this.$vbtn.css('height', sliderHeight);
        },    
        _initVbtnDragEvent: function () {
            var _this = this;
            var slider = this.$vbtn;
            var doc = this.$doc,
                dragStartPostion,
                dragStartScrollPostion,
                dragContBarRate;//滚动比例
            function moveHandler(e) {
                e.preventDefault();
                if (dragStartPostion == null) {
                    return;
                }
                if(!_this.$vbtn.data("ishl")){
                    _this.$vbtn.css({ "background-color": _this.opts.hightColor}).data("ishl",true);
                    _this.$vbar.css({"opacity":0.9});
                }
                _this.scrollTop(dragStartScrollPostion + (e.pageY - dragStartPostion) * dragContBarRate);
            }
            slider.on('mousedown', function (e) {
                e.preventDefault();
                dragStartPostion = e.pageY;
                dragStartScrollPostion = _this.$scrollWrap[0].scrollTop;
                var scrollLen = _this.getMaxScrollTopPosition();           
                dragContBarRate = scrollLen  / _this.getMaxVbtnPosition();
                _this.scrolling = true;
                doc.on('mousemove.kscroll', moveHandler).on('mouseup.kscroll', function () {
                    doc.off('.kscroll');
                    _this.maxScrollTop = undefined;
                    _this.maxVbtnPosition = undefined;
                    _this.$vbtn.css({ "background-color": _this.opts.slider["background-color"]}).removeData("ishl");
                    _this.$vbar.css({"opacity": _this.opts.bar["opacity"]});
                    _this.scrolling = false;
                    if (_this.autoHide) {
                        _this.fadeOut();
                    }
                });
            });
        },
        getMaxScrollTopPosition: function () {
            if (typeof this.maxScrollTop === "undefined") {
                var h = this.$scrollWrap.height();
                this.maxScrollTop = Math.max(h, this.scrollHeight) - h;
            }
            return this.maxScrollTop;
        },
        getVbtnPosition: function () {
            var maxSliderPosition = this.getMaxVbtnPosition();
            return Math.min(maxSliderPosition, maxSliderPosition * this.$scrollWrap[0].scrollTop / this.getMaxScrollTopPosition());
        },
        getMaxVbtnPosition: function () {
            if (typeof this.maxVbtnPosition === "undefined") {
                this.maxVbtnPosition = this.$vbar.height() - this.$vbtn.height();
            }
            return this.maxVbtnPosition;
        },
        _bindMousewheel: function () {
            var _this = this;
            _this.$scrollWrap.on('mousewheel DOMMouseScroll', function (e) {
                e.preventDefault();
                var oEv = e.originalEvent,
                    wheelRange = oEv.wheelDelta ? - oEv.wheelDelta / 120 : (oEv.detail || 0) / 3;
                _this.scrollTop(_this.$scrollWrap[0].scrollTop + wheelRange * _this.opts.wheelStep);
                if(_this.$vbar.css("display") === "none"){                    
                    _this.showOrHideVbtn();
                    if(_this.xscroll){
                        _this.showOrHideHbtn();
                    }                   
                }
            });
        },
        showOrHideVbtn: function (scrollHeight) {
            if (this.yscroll) {
                if (!scrollHeight) {
                    scrollHeight = this.scrollHeight;
                }
                var height = this.$scrollWrap.height();
                if (scrollHeight <= height) {
                    this.$vbar.hide();
                    this.jqObj.css("padding-right", 0);
                } else {
                    this.$vbar.show();
                    if(this.opts.display === "auto" && !this.opts.setPadding){
                        this.jqObj.css("padding-right", 0);
                    }else{
                        this.jqObj.css("padding-right", this.$vbar.width() + "px");
                    }
                }
            }
        },
        scrollTop: function (v) {
            this.$scrollWrap.scrollTop(v); 
            //this.$scrollWrap.animate({scrollTop:v},50);
        },
        resetSliderPosByTimer: function () {
            var _this = this;
            clearTimeout(this.sliderPosByTimer);
            this.sliderPosByTimer = setTimeout(function () {
                _this.resetSliderPosition();
            }, 500);
        },
        /*
        *当内容发生变化时候，重置位置,
        *检查 scrollHeight \scrollWidth 是否一致判断是否发生了变化
        ****/
        resetSliderPosition: function () {
            if (this.yscroll) {
                var scrollHeight = this.$scrollWrap[0].scrollHeight;
                this.scrollHeight = scrollHeight;
                this.maxScrollTop = undefined;
                this.maxVbtnPosition = undefined;              
                if (typeof this.lastScrollHeight !== "undefined" && this.lastScrollHeight !== scrollHeight) {
                    if (this.$vbtn[0].style.top !== "0px") {
                        this.$vbtn[0].style.top = this.getVbtnPosition() + 'px';
                    }
                }
                this.lastScrollHeight = scrollHeight;
                //检查是否需要显示拖动条
                this.showOrHideVbtn(scrollHeight);
            }
            if (this.xscroll) {
                var scrollWidth = this.$scrollWrap[0].scrollWidth;
                this.scrollWidth = scrollWidth;
                this.maxScrollLeft = undefined;
                this.maxHbtnPosition = undefined;
                if (typeof this.lastScrollWidth !== "undefined" && this.lastScrollWidth !== scrollWidth) {
                    if (this.$Hbtn[0].style.left !== "0px") {
                        this.$Hbtn[0].style.left = this.getHbtnPosition() + 'px';
                    }
                }
                this.lastScrollWidth = scrollWidth;
                this.showOrHideHbtn(scrollWidth);
            }
        },
        _hightLine: function (btn) {
            var _this = this;
            btn.on({
                mouseenter: function () {
                    btn.css({ "background-color": _this.opts.hightColor}).data("ishl",true);
                    btn.parent().css({"opacity": 0.9 });
                },
                mouseleave: function () {
                    btn.css({ "background-color": _this.opts.slider["background-color"]}).removeData("ishl");
                    btn.parent().css({"opacity": _this.opts.bar["opacity"]});
                }
            });
        },
        _bindContentScrollListner: function () {
            var _this = this;
            _this.$scrollWrap.on('scroll', function () {
                if (_this.yscroll) {
                    _this.$vbtn[0].style.top = _this.getVbtnPosition() + 'px';
                }
                if(_this.xscroll){
                    _this.$Hbtn[0].style.left = _this.getHbtnPosition() + 'px';
                }
            });
        },
        fadeOut:function(){
            if(this.yscroll){
                this.$vbar.fadeOut();
            }
            if(this.xscroll){
                this.$Hbar.fadeOut();
            }
        },
        destroy: function () {
            clearInterval(this.ivt);
            clearTimeout(this.sliderPosByTimer);
            for (var p in this) {
                if (this.hasOwnProperty(p)) {
                    delete this[p];
                }
            }
        }
    };
    /**jquery插件形式提供**/
    $.fn.myscrollbar = function (options,args) {
        var opts = $.extend({}, scrollDefaults, options);
        var mainWrap = $("<div style='width:100%;height:100%;position:relative;' class='k_scroll_main_wrap k_box_size'></div>");
        var scrollWrap = $("<div style='position:relative;width:100%;height:100%;overflow:hidden;' class='k_scroll_wrap k_box_size'></div>").appendTo(mainWrap);
        var parent = this.parent();
        this.detach().appendTo(scrollWrap);
        opts.yscroll = opts.axis === "xy" || opts.axis === "y";
        opts.xscroll = opts.axis === "xy" || opts.axis === "x";
        if (opts.yscroll) {
            mainWrap.css("padding-right", opts.size);
            if(opts.display === "auto" && !opts.setPadding){
                mainWrap.css("padding-right", 0);
            }            
            $("<div class='k_scroll_v_bar' style='overflow:hidden;position: absolute;top: 0;right: 0;width:"+opts.size+";height: 100%;background-color: #e4e4e4;'><div style='cursor:pointer; position: absolute;top: 0;left: 0;width:"+opts.size+";height: 30px;background-color: #525252;'></div></div>").appendTo(mainWrap);
        }
        if (opts.xscroll) {
            mainWrap.css("padding-bottom", opts.size);           
            $("<div class='k_scroll_h_bar' style='overflow:hidden;position: absolute;left: 0;bottom: 0;width:100%;height:"+opts.size+";background-color: #e4e4e4;'><div style='cursor:pointer; position: absolute;top: 0;left: 0;width:50px;height:"+opts.size+";background-color: #525252;'></div></div>").appendTo(mainWrap);
        }
        parent.append(mainWrap);
        var ins = new scrollbar(mainWrap, opts);
        this.data("scrollIns", ins);
        return this;
    };
    $.fn.getMyScrollIns = function () {
        return this.data("scrollIns");
    };

    /***
     * 滑块控件 
     * @Author: kevin.huang 
     * @Date:  2019-02-06 22:26:01
     * Copyright (c): kevin.huang Released under MIT License
     * options = {
     *      width:'100%',
     *      height: 26,
     *      start: 0 ,
     *      end : 0 ,
     *      onChange:fn(val)     
     * }
     * ****/
    $.fn.myslider = function (options, args) {
        var opts;
        var isMethodCall = typeof options === "string";
        if (!isMethodCall) {
            opts = $.extend({}, {
                width: '100%',
                height: 16,
                start: 0,
                end: 100
            }, options);
            this.data("opts", opts);
        }
        this.each(function () {
            var $t = $(this);
            var maxLeft;
            var rate;
            if (isMethodCall) {
                if (options === "setValue" || options === "setValueSilent") {
                    var opt = $t.data("opts");
                    var itWrap = $t.children("div");
                    var mvbtn = itWrap.children("span");
                    if (!rate) {
                        maxLeft = itWrap.width() - mvbtn.width();
                        rate = maxLeft / (opt.end - opt.start);
                    }
                    var infPx = args * rate;
                    mvbtn.css("left", infPx);
                    if (opt.onChange && options !== "setValueSilent") {
                        opt.onChange(args, true);
                    }
                }
                return true;
            }
            var wrap = $("<div style='z-index:1; position:relative;border:1px solid #c5c5c5;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius: 3px;'></div>");
            wrap.css({
                width: opts.width,
                height: opts.height
            });
            var btn = $("<span tabindex='0' style='cursor:pointer;background:#fff;position:absolute;z-index:2; border:1px solid #c5c5c5;top:-4px;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius: 3px;width:12px;height:" + (opts.height + 6) + "px'/>").appendTo(wrap);
            wrap.appendTo($t);
            btn.draggable({
                axis: 'h',
                onStartDrag: function (args) { //开始拖动                    
                    if (!rate) {
                        maxLeft = wrap.width() - btn.width();
                        rate = maxLeft / (opts.end - opts.start);
                    }
                },
                onDrag: function (args) { //拖动中
                    var state = args.state;
                    var data = state._data;
                    if (data.left < 0) {
                        data.left = 0;
                    } else if (data.left > maxLeft) {
                        data.left = maxLeft;
                    }
                    var val = parseInt(data.left / rate);
                    if (opts.onChange) {
                        opts.onChange(val);
                    }
                }
            }).keydown(function (e) {
                var which = e.which;
                var $t = $(this);
                var val;
                if (which === 39) {
                    val = $t.position().left + 1;
                    if (typeof maxLeft === "undefined") {
                        maxLeft = wrap.width() - btn.width();
                    }
                    if (val <= maxLeft) {
                        if (val < 0) {
                            val = 0;
                        }
                        if (val > maxLeft) {
                            val = maxLeft;
                        }
                        $t.css("left", val);
                    }
                } else if (which === 37) {
                    val = $t.position().left - 1;
                    if (val < 0) {
                        val = 0;
                    }
                    if (val >= 0) {
                        $t.css("left", val);
                    }
                }
                if (typeof val !== "undefined") {
                    if (!rate) {
                        rate = maxLeft / (opts.end - opts.start);
                    }
                    val = parseInt(val / rate);
                    if (val < opts.start) {
                        val = opts.start;
                    }
                    if (val > opts.end) {
                        val = opts.end;
                    }
                    if (opts.onChange) {
                        opts.onChange(val);
                    }
                }
            });
        });
    };
    return $;
}));(function (global, factory) {
    if (typeof define === 'function' && define.amd  && !window["_all_in_"]) {
        define(['$B', 'plugin'], function (_$B) {
            return factory(global, _$B);
        });
    } else {
        if(!global["$B"]){
            global["$B"] = {};
        }
        factory(global, global["$B"]);
    }
}(typeof window !== "undefined" ? window : this, function (window, $B) {
    var defaultOpts = {
        target: undefined, //需要重置大小的目标元素
        zoomScale: false, //是否等比例缩放
        poitStyle: {
            color: '#FF292E',
            "font-size": "8px"
        }, //8个点配置，设置为undefined则不需要4点
        lineStyle: {
            "border-color": "#FF292E",
            "border-size": "1px"
        },
        onDragReady: undefined,
        dragStart: undefined,
        onDrag: undefined,
        dragEnd: undefined
    };

    function Resize(opts) {
        $B.extend(this, Resize); //继承父类
        var $body = $("body");
        this.opts = $.extend({}, defaultOpts, opts);
        this.target = this.opts.target;
        var _this = this;
        var movingTarget,
            mvFlag,
            zoomScaleUpdateSet = {},
            tgsize,
            tgpos;
        function _dragStart(args) {
            var state = args.state;
            movingTarget = state.target;
            mvFlag = movingTarget.data("resizeData");
            tgsize = {
                height: _this.target.height(),
                width: _this.target.width()
            };
            tgpos = _this.target.position();
            zoomScaleUpdateSet = {};
            zoomScaleUpdateSet["line1"] = {
                width: _this.line1.outerWidth(),
                position: _this.line1.position()
            };
            zoomScaleUpdateSet["line2"] = {
                height: _this.line2.outerHeight(),
                position: _this.line2.position()
            };
            zoomScaleUpdateSet["line3"] = {
                width: _this.line3.outerWidth(),
                position: _this.line3.position()
            };
            zoomScaleUpdateSet["line4"] = {
                height: _this.line4.outerHeight(),
                position: _this.line4.position()
            };
            zoomScaleUpdateSet["point0"] = {
                position: _this.poitArr[0].position()
            };
            zoomScaleUpdateSet["point1"] = {
                position: _this.poitArr[1].position()
            };
            zoomScaleUpdateSet["point2"] = {
                position: _this.poitArr[2].position()
            };
            zoomScaleUpdateSet["point3"] = {
                position: _this.poitArr[3].position()
            };
            _this.zoomScaleUpdateSet = zoomScaleUpdateSet;

            if (_this.opts.dragStart) {
                _this.opts.dragStart.call(movingTarget, args);
            }
        }
        function _zoomUpated(state, _index, _type,update) {
            var movData = state._data;
            var leftOffset = movData.leftOffset;
            var topOffset = movData.topOffset;

            var line1Data = zoomScaleUpdateSet["line1"];
            var line2Data = zoomScaleUpdateSet["line2"];
            var line3Data = zoomScaleUpdateSet["line3"];
            var line4Data = zoomScaleUpdateSet["line4"];
            var targetCss = {};
            if (_type) { //4个点
                if (_this.opts.zoomScale) {
                    if (_index === 0 || _index === 2) {
                        topOffset = leftOffset;
                        movData.top = movData.startTop + topOffset;
                    } else {
                        topOffset = -leftOffset;
                        movData.top = movData.startTop + topOffset;
                    }
                }
                var line1Css = {},
                    line2Css = {},
                    line3Css = {},
                    line4Css = {},
                    otherOfs, w;
                if (_index === 0) {
                    line1Css["top"] = line1Data.position.top + topOffset;
                    line1Css["left"] = line1Data.position.left + leftOffset;
                    line1Css["width"] = line1Data.width - leftOffset;
                    _this.line1.css(line1Css);
                    line2Css["top"] = line2Data.position.top + topOffset;
                    line2Css["height"] = line2Data.height - topOffset;
                    _this.line2.css(line2Css);
                    line3Css["left"] = line3Data.position.left + leftOffset;
                    line3Css["width"] = line3Data.width - leftOffset;
                    _this.line3.css(line3Css);
                    line4Css["height"] = line4Data.height - topOffset;
                    line4Css["top"] = line4Data.position.top + topOffset;
                    line4Css["left"] = line4Data.position.left + leftOffset;
                    _this.line4.css(line4Css);
                    _this._updatePoitPosition(0, topOffset, 1);
                    _this._updatePoitPosition(leftOffset, 0, 3);
                    targetCss["width"] = tgsize.width - leftOffset;
                    targetCss["height"] = tgsize.height - topOffset;
                    targetCss["top"] = tgpos.top + topOffset;
                    targetCss["left"] = tgpos.left + leftOffset;
                } else if (_index === 1) {
                    line1Css["top"] = line1Data.position.top + topOffset;
                    line1Css["width"] = line1Data.width + leftOffset;
                    _this.line1.css(line1Css);
                    line2Css["top"] = line2Data.position.top + topOffset;
                    line2Css["height"] = line2Data.height - topOffset;
                    line2Css["left"] = line2Data.position.left + leftOffset;
                    _this.line2.css(line2Css);
                    line3Css["width"] = line3Data.width + leftOffset;
                    _this.line3.css(line3Css);

                    line4Css["top"] = line4Data.position.top + topOffset;
                    line4Css["height"] = line4Data.height - topOffset;
                    _this.line4.css(line4Css);
                    _this._updatePoitPosition(0, topOffset, 0);
                    _this._updatePoitPosition(leftOffset, 0, 2);
                    targetCss["width"] = tgsize.width + leftOffset;
                    targetCss["height"] = tgsize.height - topOffset;
                    targetCss["top"] = tgpos.top + topOffset;
                } else if (_index === 2) {
                    line1Css["width"] = line1Data.width + leftOffset;
                    _this.line1.css(line1Css);
                    line2Css["height"] = line2Data.height + topOffset;
                    line2Css["left"] = line2Data.position.left + leftOffset;
                    _this.line2.css(line2Css);
                    line3Css["width"] = line3Data.width + leftOffset;
                    line3Css["top"] = line3Data.position.top + topOffset;
                    _this.line3.css(line3Css);
                    line4Css["height"] = line4Data.height + topOffset;
                    _this.line4.css(line4Css);
                    _this._updatePoitPosition(leftOffset, 0, 1);
                    _this._updatePoitPosition(0, topOffset, 3);
                    targetCss["width"] = tgsize.width + leftOffset;
                    targetCss["height"] = tgsize.height + topOffset;
                } else {
                    line1Css["left"] = line1Data.position.left + leftOffset;
                    line1Css["width"] = line1Data.width - leftOffset;
                    _this.line1.css(line1Css);

                    line2Css["height"] = line2Data.height + topOffset;
                    _this.line2.css(line2Css);

                    line3Css["top"] = line3Data.position.top + topOffset;
                    line3Css["left"] = line3Data.position.left + leftOffset;
                    line3Css["width"] = line3Data.width - leftOffset;
                    _this.line3.css(line3Css);

                    line4Css["height"] = line4Data.height + topOffset;
                    line4Css["left"] = line4Data.position.left + leftOffset;
                    _this.line4.css(line4Css);

                    _this._updatePoitPosition(leftOffset, 0, 0);
                    _this._updatePoitPosition(0, topOffset, 2);

                    targetCss["width"] = tgsize.width - leftOffset;
                    targetCss["height"] = tgsize.height + topOffset;
                    targetCss["left"] = tgpos.left + leftOffset;

                }
            } else { //4条边
                if (_index === 0) {
                    otherOfs = topOffset / 2;
                    line2Css = {
                        "top": line2Data.position.top + topOffset
                    };
                    line4Css = {
                        "top": line4Data.position.top + topOffset
                    };
                    _this.line2.outerHeight(line2Data.height - topOffset);
                    _this.line4.outerHeight(line4Data.height - topOffset);
                    var point0ShiftLeft = 0;
                    var point1ShiftLeft = 0;
                    targetCss["top"] = tgpos.top + topOffset;
                    targetCss["height"] = tgsize.height - topOffset;
                    if (_this.opts.zoomScale) { //等比例缩放
                        movData.left = line1Data.position.left + otherOfs;
                        w = line1Data.width - topOffset;
                        _this.line1.outerWidth(w);
                        _this.line3.outerWidth(w);
                        _this.line3.css("left", line3Data.position.left + otherOfs);
                        line2Css["left"] = line2Data.position.left - otherOfs;
                        line4Css["left"] = line4Data.position.left + otherOfs;
                        point0ShiftLeft = otherOfs;
                        point1ShiftLeft = -otherOfs;
                        _this._updatePoitPosition(-otherOfs, 0, 2);
                        _this._updatePoitPosition(otherOfs, 0, 3);
                        targetCss["left"] = tgpos.left + otherOfs;
                        targetCss["width"] = tgsize.width - topOffset;
                    }
                    _this._updatePoitPosition(point0ShiftLeft, topOffset, 0);
                    _this._updatePoitPosition(point1ShiftLeft, topOffset, 1);
                    _this.line2.css(line2Css);
                    _this.line4.css(line4Css);
                } else if (_index === 1) {
                    otherOfs = leftOffset / 2;
                    w = line1Data.width + leftOffset;
                    line1Css = {
                        width: w
                    };
                    line2Css = {
                        left: line1Data.position.left + leftOffset
                    };
                    line3Css = {
                        width: w
                    };
                    targetCss["width"] = tgsize.width + leftOffset;
                    var p1TopOffset = topOffset;
                    var p2TopOffset = topOffset;
                    if (_this.opts.zoomScale) { //等比例缩放
                        movData.top = line2Data.position.top - otherOfs;
                        line2Css["height"] = line2Data.height + leftOffset;
                        p1TopOffset = -otherOfs;
                        p2TopOffset = otherOfs;
                        _this._updatePoitPosition(0, p1TopOffset, 0);
                        _this._updatePoitPosition(0, p2TopOffset, 3);
                        _this.line4.css({
                            height: line2Css["height"],
                            top: line4Data.position.top - otherOfs
                        });
                        _this.line1.css({
                            top: line1Data.position.top - otherOfs
                        });
                        _this.line3.css({
                            top: line3Data.position.top + otherOfs
                        });
                        targetCss["height"] = tgsize.height + leftOffset;
                        targetCss["top"] = tgpos.top - otherOfs;
                    }
                    _this._updatePoitPosition(leftOffset, p1TopOffset, 1);
                    _this._updatePoitPosition(leftOffset, p2TopOffset, 2);
                    _this.line1.css(line1Css);
                    _this.line2.css(line2Css);
                    _this.line3.css(line3Css);
                } else if (_index === 2) {
                    otherOfs = topOffset / 2;
                    var p2LeftOffset = 0;
                    var p3LeftOffset = 0;
                    var h = line2Data.height + topOffset;
                    line2Css = {
                        height: h
                    };
                    line4Css = {
                        height: h
                    };
                    line3Css = {
                        top: line3Data.position.top + topOffset
                    };
                    targetCss["height"] = tgsize.height + topOffset;
                    if (_this.opts.zoomScale) { //等比例缩放
                        movData.left = line3Data.position.left - otherOfs;
                        line3Css["width"] = line3Data.width + topOffset;
                        line1Css = {
                            "width": line3Css["width"],
                            left: line1Data.position.left - otherOfs
                        };
                        _this.line1.css(line1Css);
                        line2Css["left"] = line2Data.position.left + otherOfs;
                        line4Css["left"] = line4Data.position.left - otherOfs;
                        p2LeftOffset = otherOfs;
                        p3LeftOffset = -otherOfs;
                        _this._updatePoitPosition(-otherOfs, 0, 0);
                        _this._updatePoitPosition(otherOfs, 0, 1);
                        targetCss["width"] = tgsize.width + topOffset;
                        targetCss["left"] = tgpos.left - otherOfs;
                    }
                    _this.line2.css(line2Css);
                    _this.line4.css(line4Css);
                    _this.line3.css(line3Css);
                    _this._updatePoitPosition(p2LeftOffset, topOffset, 2);
                    _this._updatePoitPosition(p3LeftOffset, topOffset, 3);
                } else {
                    otherOfs = leftOffset / 2;
                    line1Css = {
                            width: line1Data.width - leftOffset,
                            left: line1Data.position.left + leftOffset
                        },
                        line3Css = {
                            width: line1Css.width,
                            left: line1Css.left
                        },
                        line4Css = {
                            left: line4Data.left - leftOffset
                        };
                    targetCss["width"] = tgsize.width - leftOffset;
                    targetCss["left"] = tgpos.left + leftOffset;
                    var point0TopOffset = 0;
                    var point3TopOffset = 0;
                    if (_this.opts.zoomScale) { //等比例缩放
                        point0TopOffset = otherOfs;
                        point3TopOffset = -otherOfs;
                        _this._updatePoitPosition(0, point0TopOffset, 1);
                        _this._updatePoitPosition(0, point3TopOffset, 2);
                        movData.top = line4Data.position.top + otherOfs;
                        line4Css["height"] = line4Data.height - leftOffset;
                        line2Css = {
                            height: line2Data.height - leftOffset,
                            top: movData.top
                        };
                        _this.line2.css(line2Css);
                        line1Css["top"] = line1Data.position.top + otherOfs;
                        line3Css["top"] = line3Data.position.top - otherOfs;
                        targetCss["height"] = tgsize.height - leftOffset;
                        targetCss["top"] = tgpos.top + otherOfs;
                    }
                    _this.line1.css(line1Css);
                    _this.line3.css(line3Css);
                    _this.line4.css(line4Css);
                    _this._updatePoitPosition(leftOffset, point0TopOffset, 0);
                    _this._updatePoitPosition(leftOffset, point3TopOffset, 3);
                }
            }
            if(_this.target){
                if(update){
                    _this.target.css(targetCss);
                }                
            }else{
                console.log("_this.target.css(targetCss); is null");
            }            
        }
        function _onDrag(args) {
            var state = args.state;
            var _idx = mvFlag.index;
            var _type = mvFlag._type;
            var update = true;
            if (_this.opts.onDrag) {
                var ret = _this.opts.onDrag.call(movingTarget, args);
                if(typeof ret !== "undefined"){
                    update = ret;
                }
            }
            _zoomUpated(state, _idx, _type,update);
        }
        function _dragEnd(args) {
            if (_this.opts.dragEnd) {
                _this.opts.dragEnd.call(movingTarget, args);
            }
            movingTarget = undefined;
            mvFlag = undefined;
        }
        var dragOpt = {
            nameSpace: 'dragrezie', //命名空间，一个对象可以绑定多种拖动方式
            which: 1, //鼠标键码，是否左键1,右键3 才能触发拖动，默认左右键均可
            cursor: 'move',
            axis: undefined, // v or h  水平还是垂直方向拖动 ，默认全向
            onStartDrag: _dragStart,
            onDrag: _onDrag,
            onStopDrag: _dragEnd
        };
        this.line1 = $("<div style='cursor:s-resize;height:3px;position:absolute;border-top:1px solid;display:none;z-index:2147483647' _id='k_resize_line_0' class='k_resize_element k_box_size k_resize_line_0'></div>").appendTo($body);
        this.line2 = $("<div style='cursor:w-resize;width:3px;position:absolute;border-right:1px solid;display:none;z-index:2147483647' _id='k_resize_line_1' class='k_resize_element k_box_size k_resize_line_1'></div>").appendTo($body);
        this.line3 = $("<div style='cursor:s-resize;height:3px;position:absolute;border-bottom:1px solid;display:none;z-index:2147483647' _id='k_resize_line_2' class='k_resize_element k_box_size k_resize_line_2'></div>").appendTo($body);
        this.line4 = $("<div style='cursor:w-resize;width:3px;position:absolute;border-left:1px solid;display:none;z-index:2147483647'_id='k_resize_line_3'  class='k_resize_element k_box_size k_resize_line_3'></div>").appendTo($body);
        dragOpt["cursor"] = "s-resize";
        dragOpt["axis"] = "v";
        this.line1.css(this.opts.lineStyle).draggable(dragOpt).data("resizeData", {
            _type: 0,
            index: 0
        });
        dragOpt["cursor"] = "w-resize";
        dragOpt["axis"] = "h";
        this.line2.css(this.opts.lineStyle).draggable(dragOpt).data("resizeData", {
            _type: 0,
            index: 1
        });
        dragOpt["cursor"] = "s-resize";
        dragOpt["axis"] = "v";
        this.line3.css(this.opts.lineStyle).draggable(dragOpt).data("resizeData", {
            _type: 0,
            index: 2
        });
        dragOpt["cursor"] = "w-resize";
        dragOpt["axis"] = "h";
        this.line4.css(this.opts.lineStyle).draggable(dragOpt).data("resizeData", {
            _type: 0,
            index: 3
        });
        this._fixLineStyle();
        this.poitArr = {};
        var i = 0;
        //var clzIcon = this.opts.poitStyle.icon;        
        var cursor;
        dragOpt["axis"] = undefined;
        while (i < 4) {
            if (i === 0) {
                cursor = "se-resize";
            } else if (i === 1) {
                cursor = "ne-resize";
            } else if (i === 2) {
                cursor = "se-resize";
            } else {
                cursor = "ne-resize";
            }
            dragOpt["cursor"] = cursor;
            var piontHtml = "<div style='display:none;position:absolute;z-index:2147483647;cursor:" + cursor + "' class='k_resize_element k_resize_element_point k_box_size k_resize_point_" + i + "' _id='k_resize_point_" + i + "'></div>";
            var tmp = $(piontHtml).appendTo($body);

            tmp.children().css(this.opts.poitStyle);
            tmp.draggable(dragOpt).data("resizeData", {
                _type: 1,
                index: i
            });
            this.poitArr[i] = tmp;
            i = ++i;
        }
        this.jqObj = $body.children(".k_resize_element");
        if (this.target) {
            this.bind(this.target);
        }
    }
    Resize.prototype = {
        _fixLineStyle: function () {
            this.line1.css({
                "border-left": "none",
                "border-right": "none",
                "border-bottom": "none"
            });
            this.line2.css({
                "border-left": "none",
                "border-top": "none",
                "border-bottom": "none"
            });
            this.line3.css({
                "border-left": "none",
                "border-right": "none",
                "border-top": "none"
            });
            this.line4.css({
                "border-top": "none",
                "border-right": "none",
                "border-bottom": "none"
            });
        },
        setStyle: function (pointStyle, lineStyle) {
            this.line1.css(lineStyle);
            this.line2.css(lineStyle);
            this.line3.css(lineStyle);
            this.line4.css(lineStyle);
            this._fixLineStyle();
            var _this = this;
            Object.keys(this.poitArr).forEach(function (key) {
                _this.poitArr[key].css(pointStyle);
            });
            //console.log("-------- setStyle >>>>>> ");
        },
        zoomScale: function (zoom) {
            this.opts.zoomScale = zoom;
        },
        setTarget: function (target) {
            if (!this.target || this.target[0] !== target[0]) {
                this.target = target;
            }
        },
        bind: function (target) {
            this.setTarget(target);
            this.show();
            var ofs = target.offset();
            var size = {
                width: target.outerWidth(),
                height: target.outerHeight()
            };
            this.line1.css({
                top: (ofs.top - 1) + "px",
                left: ofs.left + "px"
            }).outerWidth(size.width);
            this.line2.css({
                top: ofs.top + "px",
                left: (ofs.left + size.width - 2) + "px",
                height: size.height
            });
            this.line3.css({
                top: (ofs.top + size.height - 2) + "px",
                left: ofs.left + "px",
                width: size.width
            });
            this.line4.css({
                top: ofs.top + "px",
                left: ofs.left - 1 + "px"
            }).outerHeight(size.height);
            this._initPoitPosition();
            return this;
        },
        _updatePoitPosition: function (leftOffset, topOffset, updateKey) {
            var point = this.poitArr[updateKey];
            var poitData = this.zoomScaleUpdateSet["point" + updateKey];
            point.css({
                top: poitData.position.top + topOffset,
                left: poitData.position.left + leftOffset
            });
        },
        _initPoitPosition: function () {
            var poitKesy = Object.keys(this.poitArr);
            if (poitKesy.length > 0) {
                var line1Data = {
                    width: this.line1.outerWidth(),
                    position: this.line1.position()
                };
                var line2Data = {
                    height: this.line2.outerHeight(),
                    position: this.line2.position()
                };
                var line3Data = {
                    width: this.line3.outerWidth(),
                    position: this.line3.position()
                };
                //var line4Data = {height:this.line4.outerHeight(),position:this.line4.position()};
                var _this = this;
                poitKesy.forEach(function (idx) {
                    var key = parseInt(idx);
                    var poit = _this.poitArr[key];
                    var w = poit.width() / 2;
                    var h = poit.height() / 2;
                    var _pos;
                    if (key === 0) {
                        _pos = {
                            top: (line1Data.position.top - h) + "px",
                            left: (line1Data.position.left - 3) + "px"
                        };
                    } else if (key === 1) {
                        _pos = {
                            top: (line1Data.position.top - h) + "px",
                            left: (line2Data.position.left - 2) + "px"
                        };
                    } else if (key === 2) {
                        _pos = {
                            top: (line3Data.position.top - 2) + "px",
                            left: (line2Data.position.left - 2) + "px"
                        };
                    } else if (key === 3) {
                        _pos = {
                            top: (line3Data.position.top - 2) + "px",
                            left: (line3Data.position.left - w) + "px"
                        };
                    }
                    poit.css(_pos);
                });
            }
        },
        _drag: function (flag, opt) {  
            var _this = this;          
            if (flag === "line") {
                this.line1.draggable(opt, "dragrezie");
                this.line2.draggable(opt, "dragrezie");
                this.line3.draggable(opt, "dragrezie");
                this.line4.draggable(opt, "dragrezie");
            }else if (flag === "point") {                
                Object.keys(this.poitArr).forEach(function (idx) {
                    var key = parseInt(idx);
                    var poit = _this.poitArr[key];
                    poit.draggable(opt, "dragrezie");
                });
            }else if(flag === "right"){
                this.line2.draggable(opt, "dragrezie");
                this.line3.draggable(opt, "dragrezie");
                this.poitArr[1].draggable(opt, "dragrezie");
                this.poitArr[2].draggable(opt, "dragrezie");
            }else if(flag === "left"){
                this.line1.draggable(opt, "dragrezie");
                this.line4.draggable(opt, "dragrezie");
                this.poitArr[0].draggable(opt, "dragrezie");
                this.poitArr[3].draggable(opt, "dragrezie");
            }else{
                this.line1.draggable(opt, "dragrezie");
                this.line2.draggable(opt, "dragrezie");
                this.line3.draggable(opt, "dragrezie");
                this.line4.draggable(opt, "dragrezie");              
                Object.keys(this.poitArr).forEach(function (idx) {
                    var key = parseInt(idx);
                    var poit = _this.poitArr[key];
                    poit.draggable(opt, "dragrezie");
                });
            }
        },
        /**
         * 禁用拖动
         * flag[line/point/left/right] 不传值则禁用所有
         * line:禁用线
         * point:禁用点
         * left：禁用上边线，左边线，左边点
         * right:禁用下边线，右边线，右边点
         * **/
        disable: function (flag) {
            this._drag(flag, "disable");
        },
        /**
         * 启用拖动 
         * flag[line/point/left/right] 不传值则启用所有
         * line:启用线
         * point:启用点
         * left：启用上边线，左边线，左边点
         * right:启用下边线，右边线，右边点   
         * **/
        enable: function (flag) {
            this._drag(flag, "enable");
        },
        unbind: function () {            
            this.target = undefined;
            this.hide();
            return this;
        },
        show: function (target) {
            if (target) {
                this.bind(target);
            } else {
                var _this = this;
                this.line1.show();
                this.line2.show();
                this.line3.show();
                this.line4.show();
                Object.keys(this.poitArr).forEach(function (key) {
                    _this.poitArr[key].show();
                });
            }
            return this;
        },
        hide: function (target) {
            if (!target || (this.target && target && target[0] === this.target[0])) {
                this.line1.hide();
                this.line2.hide();
                this.line3.hide();
                this.line4.hide();
                var _this = this;
                Object.keys(this.poitArr).forEach(function (key) {
                    _this.poitArr[key].hide();
                });
            }
            return this;
        },
        isHide: function () {
            return this.line1.css("display") === "none";
        },
        isShow: function () {
            return this.line1.css("display") !== "none";
        },
        destroy: function () {
            this.super.destroy.call(this);
        }
    };
    $B["Resize"] = Resize;
    return Resize;
}));(function (global, factory) {
    if (typeof define === 'function' && define.amd) {
        define(['$B', 'plugin', "panel", "ctxmenu"], function (_$B) {
            return factory(global, _$B);
        });
    } else {
        if(!global["$B"]){
            global["$B"] = {};
        }
        factory(global, global["$B"]);
    }
}(typeof window !== "undefined" ? window : this, function (window, $B) {// _this.iframe.css({"vertical-align":"top","display":"block"});
    var hasIns = false;   
    window["_tab_more_close_fn"] = function(){
        if(hasIns){
            var moreWraps = $("body").children(".k_tab_more_menu_wrap");      
            moreWraps.hide();
        }        
    }; 
    /***全局关闭***/
    $(window).on('mouseup.tab_more_close', function () { 
        if(hasIns){
            window["_tab_more_close_fn"]();
        }        
        setTimeout(function() {            
            if(window.parent !== window.self && window.parent["_tab_more_close_fn"]){              
                window.parent["_tab_more_close_fn"]();
            }
        }, 10);
    });
    var iframeHtml = "<iframe  class='panel_content_ifr' frameborder='0' style='overflow:visible;padding:0;margin:0;display:block;vertical-align:top;' scroll='none'  width='100%' height='100%' src='' ></iframe>";
    var loadingHtml = "<div class='k_box_size' style='position:absolute;z-index:2147483600;width:100%;height:26px;top:2px;left:0;' class='loading'><div class='k_box_size' style='filter: alpha(opacity=50);-moz-opacity: 0.5;-khtml-opacity: 0.5;opacity: 0.5;position:absolute;top:0;left:0;width:100%;height:100%;z-index:2147483600;background:#03369B;'></div><div class='k_box_size' style='width:100%;height:100%;line-height:26px;padding-left:16px;position:absolute;width:100%;height:100%;z-index:2147483611;color:#fff;text-align:center;'><i style='color:#fff;font-size:16px;' class='fa animate-spin fa-spin6'></i><span style='padding-left:5px;font-weight:bold;color:#fff;'>" + $B.config.loading + "</span></div></div>";
    /**加载数据**/
    function _load(onLoaded) {        
        var _this = this;
        var opt = this.data("data");
        if(!opt){
            return;
        }
        var isFun = typeof onLoaded === 'function';
        _this.children().remove();
        _this.html("");
        var loading;
        var url = opt.url;
        if(url.indexOf("?") > 0){
            url = url + "&_t_="+$B.generateMixed(5);
        }else{
            url = url + "?_t_="+$B.generateMixed(5);
        }
        loading = $(loadingHtml).appendTo(_this);
        if (opt.dataType === "html") {           
            $B.htmlLoad({
                target: _this,
                url: url,
                onLoaded: function () {
                    loading.fadeOut(function(){
                        $(this).remove();
                    });
                    if (isFun) {
                        onLoaded.call(_this, opt.title);
                    }
                    $B.bindTextClear(_this);
                }
            });
        } else if (opt.dataType === "json") {           
            $B.request({
                dataType: 'json',
                url: url,
                ok: function (message, data) {
                    if (isFun) {
                        onLoaded.call(_this, opt.title, data);
                    }
                },
                final: function (res) {
                    loading.fadeOut(function(){
                        $(this).remove();
                    });
                }
            });
        } else {
            var iframe = $(iframeHtml);
            var ifr = iframe[0];         
            iframe.on("load",function(){
                loading.fadeOut(function(){
                    $(this).remove();
                });               
                if (isFun) {
                    onLoaded.call(_this, opt.title);
                }
            });
            ifr.src = url;            
            iframe.appendTo(_this);
        }
    }
    /**创建**/
    function _createItem(_opt, lineHeight) {
        var _this = this;
        var clrAttr = "line-height:" + lineHeight + "px;";
        var isClick = typeof _this.opts.onClick === 'function';
        var isCloseFn = typeof _this.opts.onClosed === 'function';
        var $li = $("<li  title='" + _opt.title + "' class='k_box_size' style='" + clrAttr + "'>" + _opt.title + "</li>").appendTo(this.$ul).click(function (e) {
            _this.$moreWrap.hide();
            var $t = $(this),
                index = 0,
                prev = $t.prev();
            while (prev.length > 0) {
                index++;
                prev = prev.prev();
            }
            var currentActived = _this.$ul.data("actived");
            if (currentActived && currentActived.attr("title") !== $t.attr("title")) {
                _this.$ul.data("activedItem").css("z-index",-1);
                var color = _this.$ul.parent().parent().css("background-color");
                currentActived.animate({
                    "backgroundColor": color
                },100, function () {
                    currentActived.removeClass("actived");
                    currentActived.attr("style", clrAttr);
                    if (isClick && !e.isTrigger) {
                        var data = $t.data("itdata");
                        _this.opts.onClick.call($t, $t.attr("title"),data);
                    }
                });
            }
            _this.$ul.data("actived", $t.addClass("actived"));
            $t.attr("style", clrAttr);
            var currentIt = _this.$body.children(".k_tab_item").eq(index).css("z-index",1);
            _this.$ul.data("activedItem", currentIt);
            currentIt.siblings().css("z-index",-1);
            if (_this.ctxmenu) {
                _this.ctxmenu.hide();
            }
            return false;
        });
        if(_opt.data){
            $li.data("itdata", _opt.data);
        }
        if (_opt.iconCls && _opt.iconCls !== '') {
            $li.prepend('<i class="fa ' + _opt.iconCls + '"></i>&nbsp');
        }
        var $it = $("<div style='z-index:-1;overflow: auto;background:#ffffff;' class='k_tab_item k_box_size'></div>").appendTo(this.$body);
        if (_opt.url && _opt.url !== "") {
            $it.data("data", {
                dataType: _opt.dataType,
                url: _opt.url,
                onLoaded: _opt.onLoaded,
                title: _opt.title
            });
            _load.call($it, _this.opts.onLoaded);
        } else if(_opt.content){
            $it.html(_opt.content);
            //$B.scrollbar($it);
        }
        if (_opt.actived) {
            $li.trigger("click");
        }
        if (_opt.closeable) {
            $("<a style='display:none;' class='close'><i class='small-font smallsize-font fa fa-cancel-2 '></i></a>").appendTo($li).click(function () {
                var $p = $(this).parent();
                var $t;
                _this.$moreWrap.hide();
                if ($p.hasClass("actived")) {
                    var next = $p.next();
                    if (next.length > 0) {
                        $t = next.trigger("click");
                    } else {
                        var prev = $p.prev();
                        if (prev.length > 0) {
                            $t = prev.trigger("click");
                        } else {
                            _this.removeData("activedItem");
                            _this.removeData("actived");
                        }
                    }
                }
                var tmp = $p.prev(),
                    idx = 0;
                while (tmp.length > 0) {
                    tmp = tmp.prev();
                    idx++;
                }
                var _tilte = $p.attr("title");
                var itData = $p.data("itdata");
                $p.remove();
                _this.$body.children().eq(idx).remove();
                var ul_left = _this.$ul.position().left;
                var lsIt = _this.$ul.children().last();
                var lsdiff = lsIt.position().left + lsIt.outerWidth() + ul_left;
                if (ul_left < 0) {
                    if (lsdiff <= _this.$headerUlWrap.width()) {
                        _this.rightButton.addClass("k_tab_icon_btn_disabeld");
                    }
                    var shiftDiff = _this.$headerUlWrap.width() - lsdiff;
                    var newLeft = ul_left + shiftDiff;
                    if (newLeft > 0) {
                        newLeft = 0;
                        _this.leftButton.removeClass("k_tab_icon_btn_disabeld");
                    }
                    _this.$ul.animate({
                        "left": newLeft
                    }, 150);
                } else {
                    _this.leftButton.addClass("k_tab_icon_btn_disabeld");
                    if (lsdiff <= _this.$headerUlWrap.width()) {
                        _this.rightButton.removeClass("k_tab_icon_btn_disabeld");
                    }
                }
                if (isCloseFn) {
                    setTimeout(function () {
                        _this.opts.onClosed(_tilte,itData);
                    }, 1);
                }
            });
            $li.on({
                mouseenter:function(){
                    var $t = $(this);
                    $t.children("a.close").show();
                },
                mouseleave:function(){
                    var $t = $(this);
                    $t.children("a.close").hide();
                }
            });
        }
        var liwidth = $li.outerWidth();
        var curLeft = liwidth + $li.position().left; //$B.Math.add(liwidth, $li.position().left);
        var wrapw = this.$headerUlWrap.outerWidth();
        var diff = curLeft - wrapw; //$B.Math.sub(curLeft, wrapw);
        if (diff > 0) {
            this.leftButton.show().removeClass("k_tab_icon_btn_disabeld");
            this.rightButton.show().addClass("k_tab_icon_btn_disabeld");
            var _tmp = diff.toString();
            if (_tmp.indexOf(".") > 0) {
                diff = parseInt(_tmp.split(".")[0]) + 2;
            }
            this.$ul.animate({
                "left": -diff
            }, 150);
        }
        return $li;
    }
    function Tab(jqObj, opts) {       
        hasIns = true;
        $B.extend(this, Tab);
        this.jqObj = jqObj.addClass("k_tab_main k_box_size");
        this.opts = opts;
        this.$header = $("<div class='k_tab_header_wrap k_box_size k_tab_icon k_tab_icon_header_bg'><div class='k_tab_header_wrap_bottom_border k_box_size'></div></div>").appendTo(this.jqObj).children();
        this.$headerUlWrap = $("<div class='k_tab_header_ulwrap'></div>").appendTo(this.$header);
        var _h = this.$header.outerHeight();
        this.$body = $("<div class='k_tab_item_body k_box_size'></div>").appendTo(this.jqObj).css("border-top", _h + "px solid #ffffff");
        this.leftButton = $("<div style='left:0' class='k_tab_button_wrap_wrap k_tab_left_btn k_box_size'><div><i class='fa fa-angle-double-left'></i></div></div>").appendTo(this.$header).children();
        this.rightButton = $("<div  style='right:0' class='k_tab_button_wrap_wrap k_tab_right_btn k_box_size'><div><i style='' class='fa fa-angle-double-right'></i></div></div>").appendTo(this.$header).children();
        this.$ul = $("<ul class='k_box_size'></ul>").appendTo(this.$headerUlWrap);
        var $b = $(window.document.body);
        this.$moreWrap = $("<div style='width:auto;height:auto;' class='k_tab_more_menu_wrap k_box_shadow'><ul></ul></div>").appendTo($b).hide();
        var lineHeight = this.$ul.height(),
            w = 0;
        for (var i = 0, l = this.opts.tabs.length; i < l; ++i) {
            w = w + _createItem.call(this, this.opts.tabs[i], lineHeight);
        }        
        var _this = this;
        this.leftButton.children("i").css("line-height",lineHeight+"px");
        this.rightButton.children("i").css("line-height",lineHeight+"px");
        function findRightLi() {
            var _lft = _this.$ul.position().left;
            var $end = _this.$ul.children().last();
            var endx = $end.outerWidth() + $end.position().left;
            var len = endx + _lft; 
            var wraplen = _this.$headerUlWrap.outerWidth();
            while (len > wraplen) {
                $end = $end.prev();
                endx = $end.outerWidth() + $end.position().left; 
                len = endx + _lft; 
            }
            var findLi = $end.next();
            if (findLi.length > 0) {
                return findLi;
            }
            return null;
        }
        this.rightButton.on({
            mouseenter: function () {
                var _$t = $(this);
                if (_$t.hasClass("k_tab_icon_btn_disabeld")) {
                    return;
                }
                var findLi = findRightLi();
                if (findLi !== null) {
                    var $ul = _this.$moreWrap.children();
                    $ul.children().remove();
                    var offset = _$t.offset();
                    _this.$moreWrap.css({
                        top: offset.top + _$t.outerHeight()
                    }).hide();
                    var help = 0;
                    var _click = function () {
                        var _$t = $(this);
                        var idx = parseInt(_$t.attr("idx"));
                        var count = _$t.parent().children().length;
                        var loop = count - idx;
                        var closeLi = _this.$ul.children().last();
                        if (loop === 1) {
                            _this.rightButton.addClass("k_tab_icon_btn_disabeld");
                        }
                        while (loop > 1) {
                            closeLi = closeLi.prev();
                            loop--;
                        }
                        closeLi.trigger("click");
                        var ulWrapLen = _this.$headerUlWrap.width();
                        var ul_left = Math.abs(_this.$ul.position().left);
                        var shift = closeLi.position().left + closeLi.outerWidth() - (ul_left + ulWrapLen);
                        if (shift > 0) {
                            _this.$ul.animate({
                                "left": -(ul_left + shift)
                            },200, function () {
                                if (typeof _this.opts.onClick === 'function') {
                                    _this.opts.onClick.call(closeLi, closeLi.attr("title"));
                                }
                            });
                            _this.leftButton.show().removeClass("k_tab_icon_btn_disabeld");
                        }
                        _this.$moreWrap.hide();
                        return false;
                    };
                    var _close = function () {
                        var _$t = $(this).parent();
                        var idx = parseInt(_$t.attr("idx"));
                        var count = _$t.parent().children().length;
                        var loop = count - idx;
                        var closeLi = _this.$ul.children().last();
                        while (loop > 1) {
                            closeLi = closeLi.prev();
                            loop--;
                        }
                        closeLi.find(".close").trigger("click");
                        var nextLi = _$t.next();
                        while (nextLi.length > 0) {
                            nextLi.attr('idx', idx--);
                            nextLi = nextLi.next();
                        }
                        var ul = _$t.parent();
                        _$t.remove();
                        if(ul.children().length === 0){
                            ul.parent().hide();
                        }
                        return false;
                    };
                    findLi.clone().appendTo($ul).attr("idx", help).click(_click).children(".close").click(_close);
                    var next = findLi.next();
                    while (next.length > 0) {
                        help++;
                        next.clone().appendTo($ul).attr("idx", help).click(_click).children(".close").click(_close);
                        next = next.next();
                    }
                    _this.$moreWrap.css("left", offset.left - _this.$moreWrap.outerWidth() + 16).show();
                } else {
                    _this.$moreWrap.hide();
                }
            },
            click: function () {
                _this.$moreWrap.hide();
                var _$t = $(this);
                var $icon = _$t.children();
                if ($icon.hasClass("k_tab_icon_right_disabeld")) {
                    return;
                }
                var findLi = findRightLi();
                if (findLi !== null) {
                    _this.leftButton.show().removeClass("k_tab_icon_btn_disabeld");
                    var _left = _this.$ul.position().left;
                    var showWidth = _this.$headerUlWrap.outerWidth() - (findLi.position().left + _left); 
                    var shift = findLi.outerWidth() - showWidth; 
                    var _tmp = (_left - shift).toString();
                    if (_tmp.indexOf(".") > 0) {
                         _tmp = parseInt(_tmp.split(".")[0]) - 2;
                    }
                    _this.$ul.animate({
                        "left": _tmp
                    }, 300, function () {
                        if (findLi.next().length === 0) {
                            _this.rightButton.removeClass("k_tab_icon_btn_disabeld");
                        }
                        _$t.trigger("mouseenter");
                    });
                } else {
                    _this.rightButton.addClass("k_tab_icon_btn_disabeld");
                }
                return false;
            }
        });
        this.leftButton.on({
            mouseenter: function () {
                var _$t = $(this);
                if (_$t.hasClass("k_tab_icon_btn_disabeld")) {
                    return;
                }
                var lft = _this.$ul.position().left;
                if (lft >= 0) {
                    _$t.addClass("k_tab_icon_btn_disabeld");
                    return;
                }
                var $start = _this.$ul.children().first();
                var $ul = _this.$moreWrap.children();
                $ul.children().remove();
                var offset = _$t.offset();
                _this.$moreWrap.css({
                    top: offset.top + _$t.outerHeight()
                }).hide();
                var help = 0;
                var absLft = parseInt(Math.abs(lft));
                var start_w = $start.outerWidth();
                var _pos = $start.position().left + start_w; 
                var diff = _pos - absLft; 
                var _click = function () {
                    var $li = $(this);
                    var idx = parseInt($li.attr("idx"));
                    var targetLi = _this.$ul.children().eq(idx).trigger("click");
                    var targetLeft = targetLi.position().left;
                    _this.$ul.animate({
                        "left": -targetLeft
                    }, 200, function () {
                        if (typeof _this.opts.onClick === 'function') {
                            _this.opts.onClick.call(targetLi, targetLi.attr("title"));
                        }
                    });
                    _this.$moreWrap.hide();
                    if (idx === 0) {
                        _$t.addClass("k_tab_icon_btn_disabeld");
                    }
                    if (_this.$ul.children().last().position().left > _this.$headerUlWrap.width()) {
                        _this.rightButton.removeClass("k_tab_icon_btn_disabeld");
                    }
                    return false;
                };
                var _close = function () {
                    var $li = $(this).parent();
                    var ul = $li.parent();
                    var idx = parseInt($li.attr("idx"));
                    var cli = _this.$ul.children().eq(idx);
                    cli.children(".close").trigger("click");
                    $li.remove();
                    if(ul.children().length === 0){
                        ul.parent().hide();
                    }
                    return false;
                };
                $start.clone().prependTo($ul).attr("idx", help).click(_click).children(".close").click(_close);
                while (diff < 0) {
                    help++;
                    $start = $start.next();
                    start_w = $start.outerWidth();
                    _pos = $start.position().left + start_w; 
                    diff = _pos - absLft; 
                    $start.clone().prependTo($ul).attr("idx", help).click(_click).children(".close").click(_close);
                }
                _this.$moreWrap.css("left", offset.left).show();
            },
            click: function () {
                _this.$moreWrap.hide();
                var _$t = $(this);
                if (_$t.hasClass("k_tab_icon_btn_disabeld")) {
                    return;
                }
                var lft = _this.$ul.position().left;
                if (lft >= 0) {
                    _$t.addClass("k_tab_icon_btn_disabeld");
                    return;
                }
                var absLft = parseInt(Math.abs(lft));
                var $start = _this.$ul.children().first();
                var start_w = $start.outerWidth();
                var _pos = $start.position().left + start_w; 
                var diff = _pos - absLft; 
                while (diff < 0) {
                    $start = $start.next();
                    start_w = $start.outerWidth();
                    _pos = $start.position().left + start_w;
                    diff = _pos - absLft; 
                }
                var newLeft = lft + start_w - diff; 
                //var newLeft = diff;
                var shift = parseInt(newLeft);
                if (shift === _this.$ul.position().left) {
                    shift = parseInt(shift + $start.prev().outerWidth());
                }
                _this.$ul.animate({
                    "left": shift
                }, 200, function () {
                    if ($start.prev().length === 0) {
                        _$t.addClass("k_tab_icon_btn_disabeld");
                    }
                    _$t.trigger("mouseenter");
                });
                _this.rightButton.removeClass("k_tab_icon_btn_disabeld");
                return false;
            }
        });
        delete this.opts.tabs;             
        if (_this.opts.cxtmenu) {
            $("body").contextmenu(function () {
                return false;
            });
            var children = this.$ul.children().mousedown(function () {
                _this.ctxtarget = $(this);
            });
            if (typeof _this.opts.cxtmenu === 'array') {
                this.ctxmenu = new $B.Ctxmenu(children, _this.opts.cxtmenu);
            } else {
                this.ctxmenu = new $B.Ctxmenu(children, [{
                    text: $B.config.tabMenu.closeAll,
                    iconCls:'fa-cancel',
                    click: function () {
                        _this.$moreWrap.hide();
                        var rmItem = [];
                        var rmBody = [];
                        var liArray = _this.$ul.children();
                        liArray.each(function(i){
                            var li = $(this);
                            if(li.children("a.close").length > 0){
                                rmBody.push( _this.$body.children().eq(i) );
                                rmItem.push(li);
                            }
                        });
                        var go2Trigger = false;                        
                        for(var i = 0, len = rmItem.length ; i < len ; ++i){
                            if(rmItem[i].hasClass("actived")){
                                go2Trigger = true;
                            }
                            rmItem[i].remove();                            
                            rmBody[i].remove();
                        }
                        liArray = _this.$ul.children();
                        if(liArray.length > 0){
                            if(go2Trigger){
                                _this.$ul.animate({
                                    "left": 0
                                },200, function () {
                                    liArray.first().trigger("click");
                                });
                            }                            
                        }else{   
                            _this.$ul.removeData("activedItem");
                            _this.$ul.removeData("actived");
                        }
                    }
                }, {
                    text: $B.config.tabMenu.closeRight,
                    iconCls:'fa-forward-1',
                    click: function () {
                        _this.$moreWrap.hide();
                        _this.rightButton.addClass("k_tab_icon_btn_disabeld");
                        var rmItem = [];
                        var rmBody = [];
                        var isActivedLast = false;
                        _this.$ul.children().each(function (i) {
                            var $t = $(this);
                            if ($t.attr("title") === _this.ctxtarget.attr("title")) {
                                var $next = $t.next();
                                while ($next.length > 0) { 
                                    i++;                                  
                                    var isRm = $next.children("a.close").length > 0;
                                    if(isRm){
                                        if($next.hasClass("actived")){
                                            isActivedLast = true;
                                        }
                                        rmItem.push($next);
                                        rmBody.push(_this.$body.children().eq(i) );
                                    }
                                    $next = $next.next();                                                            
                                }
                                return false;
                            }
                        });
                        for(var i = 0, len = rmItem.length ; i < len ; ++i){                           
                            rmItem[i].remove();                            
                            rmBody[i].remove();
                        }
                        if(isActivedLast){
                            _this.$ul.children().last().trigger("click");                           
                        }
                        _this.$ul.animate({
                            "left": 0
                        },200, function () {                           
                        });
                    }
                }, {
                    text: $B.config.tabMenu.closeLeft,
                    iconCls:'fa-reply-1',
                    click: function () {  
                        _this.$moreWrap.hide();  
                        var rmItem = [];
                        var rmBody = [];
                        var isActivedFirst = false;                    
                        _this.$ul.children().each(function (i) {
                            var $t = $(this);
                            if ($t.attr("title") === _this.ctxtarget.attr("title")) {
                                return false;
                            }
                            var isRm = $t.children("a.close").length > 0;
                            if(isRm){
                                if($t.hasClass("actived")){
                                    isActivedFirst = true;
                                }
                                rmItem.push($t);
                                rmBody.push(_this.$body.children().eq(i) );
                            }                            
                        });
                        for(var i = 0, len = rmItem.length ; i < len ; ++i){                           
                            rmItem[i].remove();                            
                            rmBody[i].remove();
                        }
                        if(isActivedFirst){
                            _this.$ul.children().first().trigger("click");
                        }
                        _this.$ul.animate({
                            "left": 0
                        },200, function () {                           
                        });
                    }
                }, {
                    text: $B.config.tabMenu.reload,
                    iconCls:'fa-arrows-ccw',
                    click: function () {
                        _this.$moreWrap.hide();
                        _this.reload(_this.ctxtarget.attr("title"));
                    }
                }]);
            }
        }
    }
    Tab.prototype = {
        _scroll2show:function(li){
        },
        /***
         *激活一个tab 参数 title
         ****/
        active: function (title) {
            this.$moreWrap.hide();
            this.$ul.children().each(function (j) {
                var $t = $(this);
                if ($t.attr("title") === title) {
                    if (!$t.hasClass("actived")) {
                         $t.trigger("click");
                    }
                }
            });
        },
        /***
         *刷新一个tab 参数 title
         ****/
        reload: function (title) {
            this.$moreWrap.hide();
            var _this = this;
            var i = -1;
            this.$ul.children().each(function (j) {
                var $t = $(this);
                if ($t.attr("title") === title) {
                    i = j;
                    $t.trigger("click");
                    return false;
                }
            });
            if (i !== -1) {
                var $body = this.$body.children().eq(i);
                _load.call($body, _this.opts.onLoaded);
            }
        },
        /***
         *关闭一个tab 参数 title
         ****/
        close: function (title) {            
            var _this = this;
            var i = -1;
            this.$ul.children().each(function (j) {
                var $t = $(this);
                if ($t.attr("title") === title) {
                    i = j;
                    if ($t.hasClass("actived")) {
                        var next = $t.next();
                        if (next.length > 0) {
                            next.trigger("click");
                        } else {
                            var prev = $t.prev();
                            if (prev.length > 0) {
                                prev.trigger("click");
                            } else {
                                _this.removeData("activedItem");
                                _this.removeData("actived");
                            }
                        }
                    }
                    $t.remove();
                    return false;
                }
            });
            if (i !== -1) {
                this.$body.children().eq(i).remove();
            }
        },
        /**
         *新增一个tab 参数参考tab项参数
         ***/
        add: function (opt) {
            this.$moreWrap.hide();
            var liArray = this.$ul.children();
            //查询是否已经存在对应的tab
            var exist = false;
            liArray.each(function(){
                var $t = $(this);
                if(opt.title === $t.attr("title")){
                    exist = true;
                    $t.trigger("click");
                    return false;
                }
            });
            if(!exist){
                if(this.opts.tabCount){
                    if(liArray.length > this.opts.tabCount){
                        $B.alert($B.config.tabLimit.replace("[x]",this.opts.tabCount),3);
                        return;
                    }
                }
                opt["actived"] = true;
                var $li = _createItem.call(this, opt, this.$ul.height());
                var _this = this;
                $li.mousedown(function () {
                    _this.ctxtarget = $(this);
                });
                this.ctxmenu.bandTarget($li);
            }
        },
        /***
         * 获取当前激活的tab
         * ***/
        getActived:function(){
           return this.$ul.children("li.actived");
        }
    };
    $B["Tab"] = Tab;
    return Tab;
}));(function (global, factory) {
    if (typeof define === 'function' && define.amd  && !window["_all_in_"]) {
        define(['$B'], function (_$B) {
            return factory(global, _$B);
        });
    } else {
        if(!global["$B"]){
            global["$B"] = {};
        }
        factory(global, global["$B"]);
    }
}(typeof window !== "undefined" ? window : this, function (window, $B) {    
    var $body;
    function _getBody(){
        if(!$body){
            $body = $(window.document.body).css("position", "relative");
            if(!$body.attr("_k_d_w_c")){
                $body.click(function () {
                    $body.children("#k_toolbar_drop_wrap").hide();
                });
                if(window.top !== window){
                    try{
                        $(window.top.document.body).click(function(){
                            $body.children("#k_toolbar_drop_wrap").hide();
                        });
                    }catch(ex){
                    }
                }
                $body.attr("_k_d_w_c",1);
            }
        }
        return $body;        
    }    
    var btnHtml = "<button  style='{bg}' cmd='{cmd}' id='{id}' class='k_toolbar_button k_box_size btn k_toolbar_button_{cls}'>{text}</button>";
    var disabledCls = "k_toolbar_button_disabled";
    function _btnClickHandler(e) {       
        var $t = $(this);
        if ($t.hasClass(disabledCls)) {
            return false;
        }
        if (!e.data["priv"]) {
            $B.alert({
                message: $B.permission
            });
            return false;
        }
        var ctx = $t;
        var _this = e.data._t;
        if (_this.opts.context) {
            ctx = _this.opts.context;
        }
        var clickEvent = $t.data("click");
        var methodsName = $t.data("methodsObject");
        if(!methodsName){
            methodsName = _this.opts.methodsObject;
        }
        if (typeof  clickEvent === 'function') {
            setTimeout(function() {
                clickEvent.call(ctx, $t.data("params"));
            }, 1);            
        } else {
            var mObj = window[methodsName];
            if (mObj && typeof mObj[clickEvent] === 'function') {               
                setTimeout(function() {
                    mObj[clickEvent].call(ctx, $t.data("params"));
                }, 1);
            }
        }
        if (e.data.wrap) {
            e.data.wrap.hide();
        }
        if (_this.opts.onOperated) {            
            setTimeout(function() {
                _this.opts.onOperated.call(ctx, $t.data("params"));
            }, 1);
        }     
        return false;
    }
    function createButton(opt,btnTxt,isGroup) {
        var _tool_timerOuter = null;
        var txt = this.opts.showText ? btnTxt : '';
        var _this = this ,bg,fontColor;
        bg = opt.color ? ("background-color:" + opt.color + ";") : '';
        if(bg === "" && this.opts.color !== ""){
            bg = "background-color:" + this.opts.color + ";";
        }
        fontColor = opt.fontColor ? ("color:" + opt.fontColor) : '';
        if(fontColor === "" && this.opts.fontColor !== ""){
            fontColor = "color:" + this.opts.fontColor + ";";
        }
        if (fontColor !== "") {
            bg = bg + fontColor;
        }
        var html = btnHtml.replace("{cmd}", opt.cmd).replace("{id}", opt.id).replace("{cls}", this.opts.style).replace("{text}", txt).replace("{bg}", bg);
        if (this.opts.params) {
            delete this.opts.params.Toolbar;
        }
        var $btn = $(html).appendTo(this.buttonWrap).data("params", $.extend({
            cmd: opt.cmd
        }, this.opts.params, opt.params));
        var returnBtn = $btn;
        if(isGroup){
            $btn.css({"margin-right":0,"border-radius":0,"-moz-border-radius":0,"-webkit-border-radius":0});
        }
        if (opt.disabled) {
            $btn.addClass(disabledCls);
        }
        if(txt === ""){
            $btn.attr("title", opt.text);
        }
        $btn.data("click", opt.click);
        if (opt.iconCls && opt.iconCls !== '') {
            if (_this.opts.style === 'plain') {
                $btn.attr("title", btnTxt).css("background", "none");
            }
            var fs = "";
            if (_this.opts.fontSize) {
                fs = "style='font-size:" + _this.opts.fontSize + "px'";
            }
            if (opt.childrens && opt.childrens.length > 0) {
                $btn.append('<i style="padding-left:4px" ' + fs + ' class="fa ' + opt.iconCls + '"></i>&nbsp');
            } else {
                $btn.prepend('<i ' + fs + ' class="fa ' + opt.iconCls + '"></i>&nbsp');
            }
            var iconColor = "#ffffff";
            if (opt.iconColor) {
                iconColor = opt.iconColor;
                
            }else if(this.opts.iconColor){
                iconColor = this.opts.iconColor;
            }
            $btn.children("i").css("color", iconColor);
        }
        //权限判断
        var params = $btn.data("params");
        if (params) {
            var privilage = params["privilage"];
            var priv = true;
            if (typeof privilage !== 'undefined' && privilage === "0") {
                priv = false;
                delete $btn.data("params")["privilage"];
                $btn.addClass("k_no_privilage_cls").css("color", "#D1D1D1");
            }
        }
        $btn.on("click", {
            _t: _this,
            priv: priv
        }, _btnClickHandler).data("methodsObject", opt.methodsObject);

        if (opt.childrens && opt.childrens.length > 0) {
            var wrap;
            $btn.mouseenter(function (e) {
                var $t = $(this),
                    _this = $t.data("ins"),
                    ofs = $t.offset(),
                    childrens = $t.data("childrens"),
                    minWidth = $t.outerWidth();
                wrap = _getBody().children("#k_toolbar_drop_wrap");
                if (wrap.length === 0) {
                    wrap = $("<div id='k_toolbar_drop_wrap' style='width:auto;position:absolute;display:none;top:-1000px;' class='k_box_size k_box_shadow'></div>").appendTo(_getBody());
                    wrap.mouseenter(function () {
                        clearTimeout(_tool_timerOuter);
                    }).mouseout(function (e) {
                        var $t = $(this);
                        var mleft = e.pageX,
                            mtop = e.pageY,
                            w = $t.outerWidth(),
                            h = $t.outerHeight(),
                            ofs = $t.offset();
                        var isInner = mleft >= ofs.left && mleft <= (ofs.left + w) && mtop > ofs.top && mtop <= (ofs.top + h);
                        if (!isInner) {
                            _tool_timerOuter = setTimeout(function () {
                                if (wrap) {
                                    wrap.hide();
                                }
                            }, 1500);
                        }
                    });
                } else {
                    wrap.children().remove();
                }
                var _top = ofs.top + $t.outerHeight() - 1;
                var _cs = {
                    top: "-1000px",
                    left: ofs.left,
                    "min-width": minWidth
                };
                wrap.css(_cs).show();
                for (var i = 0, len = childrens.length; i < len; ++i) {
                    var opt = childrens[i],
                        txt = _this.opts.showText ? opt.text : '',
                        methodsObject = opt["toolMethods"],
                        bg = opt.color ? ("background-color:" + opt.color) :  _this.opts.color;
                    var html = btnHtml.replace("{cmd}", opt.cmd).replace("{id}", opt.id).replace("{cls}", _this.opts.style).replace("{text}", txt).replace("{bg}", bg);
                    var $btn = $(html).appendTo(wrap).data("params", $.extend({
                        cmd: opt.cmd
                    }, _this.opts.params, opt.params));
                    if (opt.disabled) {
                        $btn.addClass(disabledCls);
                    }
                    if(txt === ""){
                        $btn.attr("title", opt.text);
                    }
                    $btn.data("click", opt.click);
                    //权限判断
                    var privilage = $btn.data("params")["privilage"];
                    var priv = true;
                    if (typeof privilage !== 'undefined' && privilage === "0") {
                        priv = false;
                        delete $btn.data("params")["privilage"];
                        $btn.addClass("k_no_privilage_cls").css("color", "#D1D1D1");
                    }
                    $btn.on("click", {
                        _t: _this,
                        wrap: wrap,
                        priv: priv
                    }, _btnClickHandler).data("methodsObject", opt.methodsObject);

                    if (opt.iconCls && opt.iconCls !== '') {
                        if (_this.opts.style === 'plain') {
                            $btn.attr("title", opt.text);
                        }
                        var fs = "";
                        if (_this.opts.fontSize) {
                            fs = "style='font-size:" + _this.opts.fontSize + "px'";
                        }
                        var iconColor =  opt.color ? opt.color : "#666666";
                        $btn.prepend('<i style="color:'+iconColor+';" ' + fs + ' class="fa ' + opt.iconCls + '"></i>&nbsp');
                    }
                }
                var _wrapHeight = wrap.outerHeight(),
                    inf_height = _wrapHeight + _top;
                var docWidth = _getBody().width();
                var wrapWidth = wrap.outerWidth() + 10;
                var avilableWidth = docWidth - ofs.left;
                var diffLeft = wrapWidth - avilableWidth;
                if (diffLeft > 0) {
                    wrap.css("left", ofs.left - diffLeft);
                }
                if (inf_height > _getBody().height()) {
                    _top = ofs.top - _wrapHeight;
                }                
                wrap.css("top",_top);                
                wrap.children().mouseover(function () {
                    clearTimeout(_tool_timerOuter);
                });
                return false;
            }).data("childrens", opt.childrens)
                .data("ins", _this).parent().mouseenter(function () {
                    if (wrap) {
                        wrap.hide();
                    }
                });
        }
        return returnBtn;
    }
    var Toolbar = function (jqObj, opts) {
        var defaultOpts = {
            params: null, //用于集成到tree datagrid时 行按钮的数据参数
            methodsObject: 'methodsObject', //事件集合对象
            align: 'left', //对齐方式，默认是left 、center、right
            style: 'normal', // plain / min  / normal /  big
            showText: true, // min 类型可以设置是否显示文字
            onOperated: undefined,//点击任何按钮都触发的回调
            buttons: [] //请参考buttons
        };
        $B.extend(this, Toolbar); //继承父类
        this.jqObj = jqObj.addClass("k_toolbar_main clearfix");
        this.buttonWrap = $("<div></div>").appendTo(this.jqObj);
        this.opts = $.extend({}, defaultOpts, opts);
        if (this.opts.align === 'center') {
            this.jqObj.css("text-align", "center");
            this.buttonWrap.css("width", "100%");
        } else {
            this.buttonWrap.css("float", this.opts.align);
        }
        for (var i = 0, l = this.opts.buttons.length; i < l; ++i) {
            var opt = this.opts.buttons[i];
            if($.isArray(opt)){
                var lastBtn;
                for(var j = 0 ,jlen = opt.length ; j < jlen; ++j){
                    lastBtn = this._createButtonByopt(opt[j],true);
                }
                if(i !== l -1){
                    lastBtn.css("border-right","1px solid #C1C1C1");
                }               
            }else{
                this._createButtonByopt(opt,false);
            }            
        }
    };
    Toolbar.prototype = {
        constructor: Toolbar,
        _createButtonByopt:function(opt,isGroup){
            var created = true;
            if (typeof opt.visualable !== 'undefined') {
                created = opt.visualable;
            }
            if (created) {
                return createButton.call(this, opt, opt.text,isGroup);
            }
        },
        /**
         *启用按钮（可以批量启用）
         *args  btnIds=[] //按钮的id数组
         ***/
        enableButtons: function (args) {           
            for (var i = 0, l = args.length; i < l; ++i) {
                var id = args[i];
                this.buttonWrap.children("#" + id).removeClass("k_toolbar_button_disabled");
            }
        },
        /**
         *禁用按钮（可以批量禁用）
         *args  btnIds=[] //按钮的id数组
         ***/
        disableButtons: function (args) {
            for (var i = 0, l = args.length; i < l; ++i) {
                var id = args[i];
                this.buttonWrap.children("#" + id).addClass("k_toolbar_button_disabled");
            }
        },
        /***
         *删除按钮（可以批量删除）
         *args btnIds=[] //按钮的id数组
         ***/
        delButtons: function (args) {
            for (var i = 0, l = args.length; i < l; ++i) {
                var id = args[i];
                this.buttonWrap.children("#" + id).remove();
            }
        },
        /**
         *添加按钮（可以批量添加）
         *args buttons=[]//按钮的json配置
         ***/
        addButtons: function (args) {
            for (var i = 0, l = args.length; i < l; ++i) {
                var opt = args[i];
                var txt = this.opts.showText ? opt.text : '';
                createButton.call(this, opt, txt);
            }
        },
        /***
         * 更新参数
         * ***/
        updateParams: function (args) {
            $.extend(this.opts.params, args);
        }
    };
    if($B){
        $B["Toolbar"] = Toolbar;
    }else{
        console.log("exception >>>");
    }   
    return Toolbar;
}));/**
 * 2019-06-01 修复checkSingle配置引起的复选事件bug
 * 2019-05-16 修正展开父节点url为null还发生请求的bug
 * 2019-05-15 新增checkSingle配置，复选时候，不联动 父级、下级联动，默认值false;
 * 2019-05-04 新增 setCheckDatas(datas)适配mvvm联动
 * ***/
(function (global, factory) {
    if (typeof define === 'function' && define.amd) {
        define(['$B', 'utils', 'toolbar'], function (_$B) {
            return factory(global, _$B);
        });
    } else {
        if(!global["$B"]){
            global["$B"] = {};
        }
        factory(global, global["$B"]);
    }
}(typeof window !== "undefined" ? window : this, function (window, $B) {    
    var $body;
    function _getBody(){
        if(!$body){
            $body = $(window.document.body).css("position", "relative");
        }
        return $body;
    }
    var defaultOpts = {
        data: null, //'数据'
        isTreeData: true,
        params: null, //远程加载时候附加的参数
        url: null, //请求数据的地址【如果有些请求参数是固定不变的，请去url中设置】
        textField: 'text', //菜单名称字段，默认为text
        idField: 'id', //菜单id字段,默认为id
        showLine: true, //显示连线
        checkSingle:false,//复选时候，不联动 父级、下级联动，默认值false
        extParamFiled: [], //异步懒加载时候，可以定义再传其他字段作为参数['filed1','filed2']，默认不设置只传pid
        canClickParent: true, //点击事件时，是否可以点击父节点
        nodeParentIcon: 'k_tree_fold_closed',//父节点图标关闭状态
        nodeParentOpenIcon: 'k_tree_fold_open',      //打开状态图标
        leafNodeIcon: 'k_tree_file_icon',                //子节点图标 
        chkEmptyIcon: 'k_tree_check_empty',            //不选
        chkAllIcon: 'k_tree_check_all',            //全选
        chkSomeIcon: 'k_tree_check_some',              //部分选
        fontIconColor: undefined,//字体图标颜色定义
        clickCheck: false, //是否点击复选       
        plainStyle: false, //true 为简单无图标样式
        forecePlainStyle:false,//强制简单样式
        onlyNodeData: false,//回调api中的参数是否只需要当前节点的数据（不带children）
        tree2list: true,//回调api中的参数是否转为列表类型
        checkbox: false, //是否需要选择框
        disChecked: false, //是否禁用复选框 默认false
        clickItemCls: 'k_tree_clicked_cls', //点击行颜色        
        toolbar: false, //是否需要工具栏,如果需要工具栏，则数据项中需要有toolbar工具栏组件的json
        methodsObject: 'methodsObject',//工具栏的按钮事件集合名
        onItemCreated: null, //项创建完成事件
        onTreeCreated: null,//树加载完成
        onClick: null, //function (data) { },//点击事件
        onloaded: null, //加载完成事件function (data) { }
        onOperated: null, //fn(pr) 工具栏任意事件都触发的事件
        onCheck: null, // function (data, params, checked) { } 选择事件,不建议注册onCheck事件，如果需要获取当前选择的数据，调用对象的getChecked即可
        onToggle: null //展开、收起回调
    };
    var loading = $("<li><div class='k_tree_item_wrap k_box_size'><div class='k_loading'></div></div></li>");
    function _makeTreeUi(_this, liTag, data, deep, params) {       
        var opts = _this.opts;
        var isLast = params.isLast;
        var isFirst = params.isFirst;
        var isParent = params.isParent;
        var $wrap = liTag.children("div");
        $wrap.data("data", data).data("params", params);       
        var $txt = $wrap.children(".k_tree_text");
        var isClosed = data.closed;
        if(!isClosed && data.children && data.children.length === 0){
            isClosed = true;
        }
        var clickNode, checkboxNode;
        var isFontIcon;
        if (isParent) {
            $wrap.attr("closed", isClosed);
        }
        var iconCls;
        if (opts.checkbox) {//需要checkbox
            iconCls = opts.chkEmptyIcon;
            if (data.checked) {
                iconCls = opts.chkAllIcon;
            }
            isFontIcon = iconCls.indexOf("fa-") > -1;
            if (isFontIcon) {
                checkboxNode = $('<div class="k_tree_check_box k_tree_font_icon k_tree_font_check"><i class="fa ' + iconCls + '"></i></div>').prependTo($wrap);
                if (opts.fontIconColor) {
                    checkboxNode.children("i").css("color", opts.fontIconColor);
                }
            } else {
                checkboxNode = $('<div class="k_tree_check_box k_tree_icon_img ' + iconCls + '"></div>').prependTo($wrap);
            }
            if (data.disChecked || _this.opts.disChecked) {
                checkboxNode.addClass("k_tree_check_disabled");
            } 
            checkboxNode.on("click", { _this: _this }, _this._checkBoxClick);
            
            if (!isParent && data.checked) {
                _this.triggerClickNodes.push(checkboxNode);
            }
        }
        if (!opts.plainStyle) {//需要图标
            if (isParent) {
                if (isClosed) {
                    iconCls = opts.nodeParentIcon;
                } else {
                    iconCls = opts.nodeParentOpenIcon;
                }
            } else {
                iconCls = opts.leafNodeIcon;
            }
            if (iconCls.indexOf("fa-") > -1) {
                clickNode = $('<div  class="k_tree_font_icon _node_"><i class="fa ' + iconCls + '"></i></div>').prependTo($wrap);
                if (opts.fontIconColor) {
                    clickNode.children("i").css("color", opts.fontIconColor);
                }
            } else {
                clickNode = $('<div class="k_tree_icon_img _node_ ' + iconCls + '"></div>').prependTo($wrap);
            }
        }
        if (opts.showLine) {//显示线样式
            if (isParent) {
                if (isClosed) {
                    if (isLast && isFirst) {//只有一个节点
                        if (deep === 0) {
                            iconCls = '_line_node_ k_tree_line_last_first_closed';
                        } else {
                            iconCls = '_line_node_ k_tree_line_last_closed';
                        }
                    } else if (isLast) {
                        iconCls = '_line_node_ k_tree_line_last_closed';
                    } else {
                        iconCls = '_line_node_ k_tree_line_closed';
                    }
                } else {
                    if (isLast && isFirst && deep === 0) {//只有一个节点
                        iconCls = '_line_node_ k_tree_line_last_first_open';
                    } else {
                        iconCls = '_line_node_ k_tree_line_open';
                        if (data.children.length === 0 && isLast) {
                            iconCls = '_line_node_ k_tree_line_last_empty_open';
                        }
                    }
                }
            } else {
                if (isLast && isFirst) {//只有一个节点
                    iconCls = 'k_tree_line_last';
                } else if (isFirst) {
                    iconCls = 'k_tree_line_cross';
                } else if (isLast) {
                    iconCls = 'k_tree_line_last';
                } else {
                    iconCls = 'k_tree_line_cross';
                }
            }
            var $tmp = $("<div class='k_tree_icon_img  " + iconCls + "'></div>").prependTo($wrap);
            if (isParent) {
                clickNode = $tmp;
            }
        }
        if (deep > 0) {
            var endCount = params["endCount"];
            var firstDiv = $wrap.children().first();
            var count = deep - endCount;
            var lineHtml, lastLineHtml;
            if (opts.showLine) {
                lineHtml = '<div class="k_tree_icon_img  k_tree_line_last"></div>';
                lastLineHtml = '<div class="k_tree_icon_img  k_tree_line_vertical"></div>';
            } else {
                lineHtml = '<div  class="k_tree_blank_div"></div>';
                lastLineHtml = '<div class="k_tree_blank_div"></div>';
            }
           
            if (isLast && endCount) {
                while (endCount > 0) {
                    firstDiv = $(lineHtml).insertBefore(firstDiv);
                    endCount--;
                }
            }
            while (count > 0) {
                firstDiv = $(lastLineHtml).insertBefore(firstDiv);
                count--;
            }            
        }
        if (clickNode) {
            clickNode.on("click", { _this: _this }, _this._parentNodeClick);
        }
        if (opts.toolbar && data.toolbar) {            
            var toolbar = $("<div class='k_tree_tools_wrap' style='width:auto;display:inline-block;height:20px;margin-left:14px;'></div>").insertAfter($txt);
            new $B.Toolbar(toolbar, {
                style: 'plain', // plain / min  / normal /  big
                showText: true, // min 类型可以设置是否显示文字
                params: data,
                methodsObject: opts.methodsObject,
                buttons: data.toolbar,
                onOperated: opts.onOperated
            });
            delete data.toolbar;
        }
    }
    function _getLiHtmlTag(data, deep, params) {
        var _this = this;
        var opts = this.opts;
        var id = data.id,
            text = data.text;
        if (data.data[opts.idField]) {
            id = data.data[opts.idField];
        }
        if (data.data[opts.textField]) {
            text = data.data[opts.textField];
        }
        var liHtml = "<li id='" + id + "'><div  deep='" + deep + "' style='display:inline-block;min-width:100%;white-space:nowrap;' class='k_tree_item_wrap k_box_size'><div class='k_tree_text k_box_size'>" + text + "</div></div></li>";
        var liTag = $(liHtml);
        _makeTreeUi(_this, liTag, data, deep, params);
        if (opts.onItemCreated) {
            opts.onItemCreated.call(liTag, data, deep, params);
        }
        liTag.on("click", { _this: _this }, _this._onClick);
        return liTag;
    }
    function _changeParentChkStatus(curNode, _this, isFontIcon) {
        if(_this.opts.checkSingle){
            return;
        }
        var deep = curNode.attr("deep");
        if (deep !== "0") {
            var data = curNode.data("data");
            var chkCount = data.checked ? 1 : 0;
            var $pli = curNode.parent();
            var siblings = $pli.siblings();
            var parentCls = _this.opts.chkEmptyIcon;
            var isParent = data.children !== undefined;
            var iconNode = curNode.children(".k_tree_check_box");
            if (isFontIcon) {
                iconNode = iconNode.children("i");
            }
            if (isParent) {
                if (iconNode.hasClass(_this.opts.chkSomeIcon)) {
                    parentCls = _this.opts.chkSomeIcon;
                }
            }
            siblings.each(function () {
                var $li = $(this);
                var chkBox = $li.children("div").children(".k_tree_check_box");
                if (isFontIcon) {
                    chkBox = chkBox.children("i");
                }
                if (chkBox.hasClass(_this.opts.chkAllIcon)) {
                    chkCount++;
                } else if (chkBox.hasClass("." + _this.opts.chkSomeIcon)) {
                    parentCls = _this.opts.chkSomeIcon;
                }
            });
            if (chkCount === siblings.length + 1) {
                parentCls = _this.opts.chkAllIcon;
            } else if (chkCount > 0) {
                parentCls = _this.opts.chkSomeIcon;
            }
            var $pul = $pli.parent();
            var parentNode = $pul.prev();
            iconNode = parentNode.children(".k_tree_check_box");
            if (isFontIcon) {
                iconNode = iconNode.children("i");
            }
            iconNode.removeClass(_this.opts.chkSomeIcon + " " + _this.opts.chkAllIcon + " " + _this.opts.chkEmptyIcon).addClass(parentCls);
            if (parentCls === _this.opts.chkAllIcon) {
                parentNode.data("data").checked = true;
            } else {
                parentNode.data("data").checked = false;
            }
            _changeParentChkStatus(parentNode, _this, isFontIcon);
        }
    }
    function _changeChildChkStatus(curNode, isFontIcon, ischeck, _this) {
        if(_this.opts.checkSingle){
            return;
        }
        var childrens = curNode.next().children();
        childrens.each(function () {
            var $li = $(this);
            var $wrap = $li.children("div");
            var iconNode = $wrap.children(".k_tree_check_box");
            if (isFontIcon) {
                iconNode = iconNode.children("i");
            }
            iconNode.removeClass(_this.opts.chkSomeIcon + " " + _this.opts.chkAllIcon + " " + _this.opts.chkEmptyIcon);
            if (ischeck) {
                iconNode.addClass(_this.opts.chkAllIcon);
                $wrap.data("data").checked = true;
            } else {
                iconNode.addClass(_this.opts.chkEmptyIcon);
                $wrap.data("data").checked = false;
            }
            var ul = $wrap.next();
            if (ul.length > 0) {
                _changeChildChkStatus($wrap, isFontIcon, ischeck, _this);
            }
        });
    }
    function _task(_this, ul, datas, deep, endCount) {
        _this.running++;
        setTimeout(function () {
            var data,
                children,
                $li, curEndCount = 0;
            var vUl = $("<ul />");
            for (var i = 0, len = datas.length; i < len; ++i) {
                var params = { isFirst: false, isLast: true, isParent: false };
                data = datas[i];
                children = data.children;
                curEndCount = 0;
                var needCount = false;
                var isClosed = data.closed;
                if (children) {
                    params.isParent = true;
                } else {
                    params.isParent = false;
                }
                if (i === 0) {
                    params.isFirst = true;
                } else {
                    params.isFirst = false;
                }
                if (i === datas.length - 1) {
                    params.isLast = true;
                    needCount = true;
                    if (params.isParent) {
                        curEndCount = 1 + endCount;
                        if (children.length > 0 && !data.closed) {
                            needCount = false;
                        }
                    }
                } else {
                    params.isLast = false;
                }
                if (needCount) {
                    params.endCount = endCount;
                } else {
                    params.endCount = 0;
                }
                $li = _getLiHtmlTag.call(_this, data, deep, params);
                $li.appendTo(vUl);
                if (children) {
                    _this._putParentRecord($li);
                    var ulStyle = "";
                    if (isClosed) {
                        ulStyle = "style='display:none;'";
                    }
                    var $childUl = $("<ul " + ulStyle + "/>").addClass("k_tree_ul").appendTo($li);
                    if (children.length > 0) {
                        _loopCreate.call(_this, $childUl, children, deep + 1, curEndCount);
                    }
                }else{
                    _this._putChildRecord($li);
                }
            }
            vUl.children().appendTo(ul);
            _this.running--;
            _this = undefined;
            ul = undefined;
            datas = undefined;
            deep = undefined;
            endCount = undefined;
        },0);
    }
    function _loopCreate(_ul, _datas, _deep, _endCount) {
        (_task)(this, _ul, _datas, _deep, _endCount);
    }
    /**根据数据创建树**/
    function _createByData(datas, deep) {
        var _this = this;
        _this.running = 0;
        _this.triggerClickNodes = [];
        var rootUl = this.jqObj;
        if ($.isPlainObject(datas)) {
            datas = [datas];
        }
        var data, children, $li, endCount, isClosed;
        for (var i = 0, len = datas.length; i < len; ++i) {
            var params = { isFirst: false, isLast: true, isParent: false };
            data = datas[i];
            isClosed = data.closed;
            children = data.children;
            endCount = 0;
            if (children) {
                params.isParent = true;
            } else {
                params.isParent = false;
            }
            if (i === 0) {
                params.isFirst = true;
            } else {
                params.isFirst = false;
            }
            if (i === datas.length - 1) {
                params.isLast = true;
                if (params.isParent) {
                    endCount = 1;
                }
            } else {
                params.isLast = false;
            }
            params["endCount"] = endCount;
            $li = _getLiHtmlTag.call(_this, data, deep, params);
            rootUl.append($li[0]);
            if (children) {
                this._putParentRecord($li);
                var ulStyle = "";
                if (isClosed) {
                    ulStyle = "style='display:none;'";
                }
                var $ul = $("<ul " + ulStyle + "/>").addClass("k_tree_ul").appendTo($li);
                if (children.length > 0) {
                    _loopCreate.call(_this, $ul, children, deep + 1, endCount);
                }
            }else{
                this._putChildRecord($li);
            }
        }
    }
    /**数据加载**/
    function _load($ul, params, callBackFn) {
        var _this = this;
        var opts = this.opts;
        var parentData,
            deep = 0;
        var $parent = $ul.prev("div.k_tree_item_wrap");
        if ($parent.length > 0) {
            parentData = $parent.data("data");
            deep = parseInt($parent.attr("deep")) + 1;
        }
        loading.find(".k_loading").css("margin-left", deep * 20);
        var $loading = loading.appendTo($ul);
        var ajaxOpts = {
            async: true,
            url: opts.url,
            data: params,
            ok: function (message, data,res) {
                console.log("loaded >>> tree");
                if(!_this.opts.isTreeData){
                    data = _this._formatData(data);
                }               
                if (parentData) {
                    var nodeParams = $parent.data("params");
                    var endCount = nodeParams.endCount;
                    _this.running = 0;
                    _this.triggerClickNodes = [];
                    parentData.children = data;
                    if(nodeParams.isLast){
                        endCount++;
                    }
                    _loopCreate.call(_this, $ul, data, deep, endCount);
                    _createCheckInterval.call(_this);
                } else {//根请求
                    opts.data = data;
                    _createByData.call(_this, data, deep);
                }
                if (opts.onloaded) {
                    setTimeout(function () {
                        opts.onloaded(data);
                    },10);
                }
            },
            fail: function (message) {
            },
            final: function (res) {
                $loading.remove();                
                if (callBackFn) {
                    setTimeout(function () {
                        callBackFn(res);
                    }, 200);
                }
                if (opts.requestfinal) {
                    opts.requestfinal();
                }
            }
        };
        this.ajax(ajaxOpts);
    }
    function _createCheckInterval() {
        var _this = this;
        var ivt = setInterval(function () {
            if (_this.running === 0) {
                clearInterval(ivt);
                _this.setRootUlWidth();
                var chkNode, isFontIcon, ul, li, trigger, siblings, $wrap, $ul;
                var resetNode = [];
                for (var i = 0, len = _this.triggerClickNodes.length; i < len; ++i) {
                    chkNode = _this.triggerClickNodes[i];
                    $wrap = chkNode.parent();
                    li = $wrap.parent();
                    if (li.data("skip")) {
                        continue;
                    }
                    isFontIcon = chkNode.hasClass("k_tree_font_check");
                    siblings = li.siblings();
                    trigger = true;
                    for (var j = 0, jlen = siblings.length; j < jlen; ++j) {
                        li = $(siblings[j]);
                        $ul = li.children("ul");
                        if ($ul.length > 0) {
                            if ($ul.children().length > 0) {
                                trigger = false;
                            }
                            break;
                        }
                    }
                    if (trigger) {
                        siblings.data("skip", true);
                        resetNode.push(siblings);
                        _changeParentChkStatus($wrap, _this, isFontIcon);
                    }
                }
                setTimeout(function () {
                    for (var k = 0, klen = resetNode.length; k < klen; ++k) {
                        resetNode[k].removeData("skip");
                    }
                    resetNode = undefined;
                },5);                
                if (_this.opts.onTreeCreated) {
                    _this.opts.onTreeCreated();
                }
            }
        },10);
    }
    var Tree = function (jqObj, opts) {
        $B.extend(this, Tree);
        this.parentNodesArray = [];
        this.childNodesArray = [];
        this.jqObj = jqObj.addClass("k_tree_ul k_tree_root k_box_size");//.css({"overflow-x":"auto","overflow-y":"visible"});
        this.jqObj.children().remove();
        this.opts = $.extend({}, {}, defaultOpts, opts);
        if (!this.opts.showLine && !this.opts.forecePlainStyle) {
            this.opts.plainStyle = false;
        }     
        this.clickedItem = null;
        if (this.opts.data && this.opts.data.length > 0) {
            if (!this.opts.isTreeData) {
                this.opts.data = this._formatData(this.opts.data);
            }
            _createByData.call(this, this.opts.data, 0);
            _createCheckInterval.call(this);
        } else if(this.opts.url && this.opts.url !== "") {
            var _this = this;
            _load.call(this, this.jqObj, { pid: "" }, function () {
                if (_this.jqObj.children().length === 0) {
                    var ofs = _this.jqObj.offset();
                    ofs.top = ofs.top + 2;
                    ofs.left = ofs.left + 12;
                    _this._tipNotDate(ofs);
                }
            });
        }  
        this.jqObj.data("treeIns",this);     
    };
    Tree.prototype = {
        setRootUlWidth:function(){
            var _this = this;
            var minWidth = this.jqObj.parent().width();
            this.minWidth = minWidth;
            this.jqObj.children().each(function(){
                var li = $(this);
                var w = 0 ;
                li.children("div").children().each(function(){
                    w = $(this).outerWidth() + w;                     
                });
                if(w > _this.minWidth){
                    _this.minWidth = w;
                }
                _this._loopVisiableUl(li.children("ul"));
            });
            this.jqObj.css("min-width" , this.minWidth);
        },
        _loopVisiableUl:function(ul){
            if(ul.length > 0 && ul.css("display") !== "none"){
                var _this = this;
                ul.children().each(function(){
                    var li = $(this);
                    var w = 0 ;
                    li.children("div").children().each(function(){
                        w = $(this).outerWidth() + w;                     
                    });
                    if(w > _this.minWidth){
                        _this.minWidth = w;
                    }
                    _this._loopVisiableUl(li.children("ul"));
                });   
            }
        },
        /**普通列表转为tree格式***/
        _formatData: function (list, pid) {
            var res = [];
            if (pid) {
            } else {
                for (var i = 0, len = list.length; i < len; ++i) {
                    var d = list[i];
                    res.push({
                        id: d[this.opts.idField],
                        text: d[this.opts.textField],
                        data: d
                    });
                }
            }
            return res;
        },
        _tree2list: function (resultArray, treeData, filterFn) {
            var _this = this;
            var data = {};
            var isParent = typeof treeData.children !== "undefined";
            var childrens = [];
            Object.keys(treeData).forEach(function (key) {
                var v = treeData[key];
                var needed = true;
                if (filterFn) {
                    needed = filterFn(key, isParent, treeData);
                }
                if (key === "children") {
                    childrens = v;
                } else {
                    if (needed) {
                        if ($.isPlainObject(v)) {
                            v = $.extend(true, {}, v);
                        }
                        data[key] = v;
                    }
                }
            });
            if (!$.isEmptyObject(data)) {
                resultArray.push(data);
            }
            if (childrens.length > 0) {
                for (var i = 0, len = childrens.length; i < len; ++i) {
                    _this._tree2list(resultArray, childrens[i], filterFn);
                }
            }
        },
        _getNodeData: function ($wrap) {
            var params = $wrap.data("params");
            var srcData = $wrap.data("data");
            var data, _this = this;
            if (params.isParent) {
                if (_this.opts.onlyNodeData) {
                    data = {};
                    Object.keys(srcData).forEach(function (key) {
                        if (key !== "children") {
                            var v = srcData[key];
                            if ($.isPlainObject(v)) {
                                v = $.extend(true, {}, v);
                            }
                            data[key] = v;
                        }
                    });
                    if (_this.opts.tree2list) {
                        data = [data];
                    }
                } else if (_this.opts.tree2list) {
                    var list = [];
                    _this._tree2list(list, srcData);
                    data = list;
                } else {
                    data = $.extend(true, {}, srcData);
                }
            } else {
                data = $.extend(true, {}, srcData);
                if (_this.opts.tree2list) {
                    data = [data];
                }
            }
            return data;
        },
        _onClick: function (e) {          
            var _this = e.data._this;
            var isClickFn = typeof _this.opts.onClick === "function";
            if(isClickFn || _this.opts.clickCheck){
                var $node = $(this);
                var $wrap = $node.children("div");
                var params = $wrap.data("params");
                if (!_this.opts.canClickParent && params.isParent) {
                    return false;
                }
                if (_this.clickedItem) {
                    _this.clickedItem.removeClass(_this.opts.clickItemCls);
                }
                _this.clickedItem = $wrap.addClass(_this.opts.clickItemCls);                
                if (_this.opts.clickCheck) {
                    var chkBox = $wrap.children(".k_tree_check_box");
                    if (!chkBox.hasClass("k_tree_check_disabled")) {
                        chkBox.trigger("click");
                    }
                } 
                if(isClickFn){
                    var data = _this._getNodeData($wrap);
                    _this.opts.onClick.call($node, data, params);
                }
            }            
            return false;
        },
        _checkBoxClick: function (e) {
            var _this = e.data._this;
            var $node = $(this);
            if(!e.isTrigger && $node.hasClass("k_tree_check_disabled")){
                return;
            }
            var $wrap = $node.parent();
            var params = $wrap.data("params");
            if (!_this.opts.canClickParent && params.isParent) {
                return false;
            }
            var data = $wrap.data("data");
            var isParent = $wrap.next().length > 0;
            var $i = $node.children("i");
            var isFontIcon = $node.hasClass("k_tree_font_icon");
            if ($i.length > 0) {
                $node = $i;
            }
            if (data.checked) {
                $node.removeClass(_this.opts.chkAllIcon).removeClass(_this.opts.chkSomeIcon).addClass(_this.opts.chkEmptyIcon);
                data.checked = false;
            } else {
                $node.removeClass(_this.opts.chkEmptyIcon).removeClass(_this.opts.chkSomeIcon).addClass(_this.opts.chkAllIcon);
                data.checked = true;
            }
            if(!_this.opts.checkSingle){
                if (isParent) {
                    _changeParentChkStatus($wrap, _this, isFontIcon);
                    _changeChildChkStatus($wrap, isFontIcon, data.checked, _this);
                } else {
                    _changeParentChkStatus($wrap, _this, isFontIcon);
                } 
            }          
            if (_this.opts.onCheck && !_this._noNotify) {
                var resData = _this._getNodeData($wrap);
                _this.opts.onCheck(resData, params, data.checked);              
            }
            if(typeof _this.onWatcher === "function"){//配合动态双向表单功能
                _this.onWatcher.call(_this);
            }
            return false;
        },
        _changeNodeUi: function ($node) {
            var $wrap = $node.parent();
            var $li = $wrap.parent();
            var isLast = $li.next().length === 0;
            var nextIcon, fixCount = 0, parentNode, $ul, $tmp;
            if ($node.hasClass("_node_")) {
                nextIcon = $node;
            } else {
                nextIcon = $node.next("._node_");
            }
            var $i = nextIcon.children("i");
            var isClosed = $wrap.next().css("display") === "none";
            if ($i.length > 0) {
                nextIcon = $i;
            }
            if (isLast && this.opts.showLine) {
                $ul = $li.parent();
                parentNode = $ul.parent();
                while ($ul[0] !== this.jqObj[0]) {
                    if (parentNode.next().length === 0) {
                        fixCount++;
                        $ul = parentNode.parent();
                        parentNode = $ul.parent();
                    } else {
                        break;
                    }
                }
            }
            if ($node.hasClass("_node_")) {
                if (isClosed) {
                    nextIcon.removeClass(this.opts.nodeParentOpenIcon).addClass(this.opts.nodeParentIcon);
                } else {
                    nextIcon.removeClass(this.opts.nodeParentIcon).addClass(this.opts.nodeParentOpenIcon);
                }
            } else {
                if (isClosed) {
                    $node.removeClass("k_tree_line_open k_tree_line_last_empty_open");
                    if (isLast) {
                        $node.addClass("k_tree_line_last_closed");
                        $tmp = $node;
                        while (fixCount > 0) {
                            $tmp = $tmp.prev().removeClass("k_tree_line_vertical").addClass("k_tree_line_last");
                            fixCount--;
                        }
                    } else {
                        $node.addClass("k_tree_line_closed");
                    }
                    nextIcon.removeClass(this.opts.nodeParentOpenIcon).addClass(this.opts.nodeParentIcon);
                } else {
                    $node.removeClass("k_tree_line_last_closed k_tree_line_closed");
                    $node.addClass("k_tree_line_open");
                    nextIcon.removeClass(this.opts.nodeParentIcon).addClass(this.opts.nodeParentOpenIcon);
                    $tmp = $node;
                    while (fixCount > 0) {
                        $tmp = $tmp.prev().removeClass("k_tree_line_last").addClass("k_tree_line_vertical");
                        fixCount--;
                    }
                }
            }
        },
        _putParentRecord:function(li){
            this.parentNodesArray.push(li);
        },
        _putChildRecord:function(li){
            this.childNodesArray.push(li);
        },
        /**
         * 节点收放事件
         * **/
        _parentNodeClick: function (e) {            
            var $node = $(this);
            if (!$node.data("busy")) {
                var $wrap = $node.parent();
                var nodeData = $wrap.data("data");
                var _this = e.data._this;
                var id = _this.opts.idField === "id" ? nodeData.id : nodeData.data[_this.opts.idField];
                var ul = $wrap.next();
                var notChildren = ul.children().length === 0;
                $node.data("busy", true);
                var ofs = $node.offset();
                var isClosed = $wrap.attr("closed");
                if (isClosed === "true") {
                    if (notChildren &&  _this.opts.url && _this.opts.url !== "") {
                        var params = { pid: id };
                        for (var i = 0, len = _this.opts.extParamFiled.length; i < len; ++i) {
                            params[_this.opts.extParamFiled[i]] = nodeData.data[_this.opts.extParamFiled[i]];
                        }
                        ul.show();
                        _load.call(_this, ul, params, function (data) {
                            $wrap.removeAttr("closed");
                            $node.removeData("busy");
                            _this._changeNodeUi($node);
                            if (ul.children().length === 0) {
                                $node.trigger("click");
                                _this._tipNotDate(ofs);
                            }
                        });
                    } else {
                        ul.slideDown(150, function () {
                            $wrap.removeAttr("closed");
                            $node.removeData("busy");
                            _this._changeNodeUi($node);
                            _this.setRootUlWidth();
                            if (notChildren) {
                                $node.trigger("click");
                                _this._tipNotDate(ofs);
                            }
                            if(_this.opts.onToggle){
                                _this.opts.onToggle("show");
                            }
                        });
                    }
                } else {
                    ul.slideUp(150, function () {
                        $wrap.attr("closed", true);
                        $node.removeData("busy");
                        _this._changeNodeUi($node);
                        _this.setRootUlWidth();
                        if(_this.opts.onToggle){
                            _this.opts.onToggle("hide");
                        }
                    });
                }
            }
            return false;
        },
        _tipNotDate: function (ofs) {
            var tip = $("<div style='width:auto;position:absolute;top:-1000px;left:" + ofs.left + "px' class='k_tree_empty_tip k_box_size'>" + $B.config.noData + "</div>").appendTo(_getBody());
            tip.css("top", ofs.top);
            setTimeout(function () {
                tip.fadeOut(450, function () {
                    tip.remove();
                });
            }, 1200);
        },
        /**
        * 重新加载数据
        @param target:节点树ul对象,可以用于只加载某个子节点	,可不传值
        @param args={p:1} 查询参数		
        ****/
        reload: function (target,args) { 
            var ul,params = {};           
            if(arguments.length === 1){
                if($.isPlainObject(target)){
                    ul = this.jqObj;
                    params = target;
                }else{
                    ul = target;                    
                }
            }else{
                ul = target;
                params = args;
            }
            var isRoot = ul[0] === this.jqObj[0];
            var _this = this , ofs;
            if(isRoot){
                ul.children().remove();
            }else{
                var pid = ul.parent().attr("id");
                params["pid"] = pid;
            }
            ul.children().remove();
            _load.call(this, ul, params, function (data) {
                if(isRoot){
                    if (_this.jqObj.children().length === 0) {
                        ofs = _this.jqObj.offset();
                        ofs.top = ofs.top + 2;
                        ofs.left = ofs.left + 12;
                        _this._tipNotDate(ofs);
                    }                   
                }else{                    
                    var $wrap = ul.prev();
                    $wrap.removeAttr("closed");
                    var $node = $wrap.children("._line_node_");
                    $node.removeData("busy");
                    ofs = $node.offset();
                    _this._changeNodeUi($node);
                    if (ul.children().length === 0) {
                        $node.trigger("click");
                        _this._tipNotDate(ofs);
                    }
                }
            });
        },
        reset:function(){
            if(this.clickedItem){
                this.clickedItem.removeClass(this.opts.clickItemCls);
                this.clickedItem = undefined;
            }
            if(this.opts.checkbox){
                for(var i = 0 ,len = this.childNodesArray.length ; i < len ;++i){
                    var li = this.childNodesArray[i];
                    var wrap = li.children("div");                   
                    if(wrap.data("data").checked){
                        wrap.children(".k_tree_check_box").trigger("click");
                    }                
                }
            }           
        },
        /***
        * 更新节点
        @param $node	节点jq对象
        @param data	更新的数据
        * ***/
        updateNode: function ($node, data) { },
        /**获取点击的项**/
        getClickItem: function () {
            if (this.clickedItem) {
                return this._getNodeData(this.clickedItem);
            }
        },
        /**
         *{
            onlyId: false,
            onlyChild: false
         }
         * **/
        getCheckedData: function (params) {
            var onlyId = false,
                onlyChild = false;
            if (params) {
                if (typeof params.onlyId !== 'undefined') {
                    onlyId = params.onlyId;
                }
                if (typeof params.onlyChild !== 'undefined') {
                    onlyChild = params.onlyChild;
                }
            }
            var res = [];
            var _this = this;
            var datas = this.opts.data;
            var filterFn = function (key, isParent, nodeData) {
                if (!nodeData.checked) {
                    return false;
                }
                var go = true;
                if (onlyId) {
                    if (key !== _this.opts.idField) {
                        go = false;
                    }
                }
                if (onlyChild && isParent) {
                    go = false;
                }
                return go;
            };
            for (var i = 0, len = datas.length; i < len; ++i) {
                this._tree2list(res, datas[i], filterFn);
            }
            return res;
        },
        getParentList:function(nodeEl){
            var tmp = [];       
            tmp.push(nodeEl.data("data"));   
            var parentUl =  nodeEl.parent().parent();
            while(parentUl.length > 0 && parentUl.hasClass("k_tree_ul")){
                if(parentUl.hasClass("k_tree_root")){
                    break;
                }
                nodeEl = parentUl.prev();
                tmp.push(nodeEl.data("data"));   
                parentUl =  nodeEl.parent().parent();
            } 
            return tmp.reverse();
        },
        /**
         * 设置勾选/选择的数据，适配mvvm联动
         * datas = []; datas = "id1,id2,id3"
         * ***/
        setCheckDatas:function(datas){           
            if(typeof datas === "string"){
                if(datas === ""){
                    datas = [];
                }else{
                    datas = datas.split(",");
                }
            }
            var dataMap = {};
            for(var i = 0 ,len = datas.length ; i < len ;++i){
                dataMap[datas[i]] = true;
            }
            var _this = this;
            this._noNotify = true;
            this.loopRoot(function($li){
                var $it = $li.children("div");
                var data = $it.data("data");
                var id = $li.attr("id");
                if(data.checked ){//如果是复选状态，则检查dataMap                    
                    if(!dataMap[id]){
                        $it.children(".k_tree_check_box").trigger("click");
                    }                   
                }else if(dataMap[id]){
                    $it.children(".k_tree_check_box").trigger("click");
                }
            });            
            this._noNotify = false;
        },
        /**
         * 设置点击的项，适配mvvm联动
         * **/
        setClickedItem:function(id){
            id = id + "";
            if(this.clickedItem){
                this.clickedItem.removeClass("k_tree_clicked_cls");
            }
            var _this = this;
            var hasFined = false;
            this.loopRoot(function($li){
                if(hasFined){
                    return true;
                }
                var $it = $li.children("div");
                if($li.attr("id") === id){
                    _this.clickedItem = $it.addClass("k_tree_clicked_cls");
                    hasFined = true;
                    return true;
                }
            });
        },
        loopRoot:function(onLoopFn){
            var _this = this;
            this.jqObj.children().each(function(){
                var $li = $(this);              
                var isBreak = onLoopFn($li);
                if(isBreak){
                    return false;
                }
                var childUl = $li.children("ul");
                if(childUl.length > 0){//子元素
                    _this.loopChild(childUl.children(),onLoopFn);
                }
            });
        },
        loopChild:function(childs,onLoopFn){
            var _this = this;
            childs.each(function(){
                var $li = $(this);
                var isBreak = onLoopFn($li);
                if(isBreak){
                    return false;
                }
                var childUl =  $li.children("ul");
                if(childUl.length > 0){//子元素
                    _this.loopChild(childUl.children(),onLoopFn);
                }
            });
        }
    };
    $B["Tree"] = Tree;
    return Tree;
}));(function (global, factory) {
    if (typeof define === 'function' && define.amd  && !window["_all_in_"]) {
        define(['$B'], function (_$B) {
            return  factory(global, _$B);
        });
    } else {
        if(!global["$B"]){
            global["$B"] = {};
        }
        factory(global, global["$B"]);
    }
}(typeof window !== "undefined" ? window : this, function (window, $B) {
    function getDateDiff(sTime, eTime) {
        return parseInt((eTime.getTime() - sTime.getTime()));
    }
    var $body;
    function _getBody(){
        if(!$body){
            $body = $(window.document.body).css("position", "relative");
        }
        return $body;
    }
    var formTag = '<form enctype="multipart/form-data"   method="post" name="k_fileUpload_from"></form>';
    /**
	 * 利用iframe模拟ajax实现多附件上传
	 * args={
		  	target:$("#div"),
		  	timeout:180, //超时时间 秒
            url:contextPath+'/bdms/menu/upload.do',
            isCross : 是否是跨域上传
            crossHelperPage: 跨域上传时候需要设置一个辅助页面,被跨域放将结果存放在crossHelperPage.Window.name
		  	// 待上传的文件列表，用于设置input的 name 以在服务器区分文件  	
			files:[{name:'xmlfile',type:'.xml',label:'提示标题',must:'是否必须上传文件'},{name:'xlsfile',type:'.xls,.xlsx',label:'提示标题'}], 
			onselected:fn(value,id,accept){ return true / false } ,//选择文件后的事件请返回true 以便通过验证
			immediate:true, //选择文件后是否立即自动上传，即不用用户点击提交按钮就上传
			success:function(res){}, //成功时候的回调
			ondeleted:function(res){ //删除回调},
			setParams:function(return {p1:111}), //设置参数
			error:fn(res), //错误回调
			reposition:fn //重设位置
	 * }
	 ****/
    function MutilUpload(args) {
        $B.extend(this, MutilUpload);
        this.target = args.target.addClass("k_mutilupload_wrap");
        this.target.children().remove();
        this.onselected = args.onselected;
        this.immediate = args.immediate;
        this.success = args.success;
        this.ondeleted = args.ondeleted;
        this.isCross = args.isCross;
        this.crossHelperPage = args.crossHelperPage;
        this.error = args.error;
        this.setParams = args.setParams;
        this.url = args.url;
        this.form = $(formTag).appendTo(this.target);
        this.timeout = (args.timeout ? args.timeout : 300) * 1000;
        this.uploading = false;
        this.init = typeof args.init === 'undefined' ? true : args.init;
        if (this.init && $.isArray(args.files)) {
            for (var i = 0, len = args.files.length; i < len; ++i) {
                this._createFileInput(args.files[i]);
                if (i < len - 1) {
                    this.form.append("<br/>");
                }
            }
        }
    }
    MutilUpload.prototype = {
        _createIframe: function (uploadFileArray) {
            var id = "_ifr_" + $B.generateMixed(8);
            var _this = this;     
            _this.isIniting = true; 
            var ifr = $('<iframe  name="' + id + '" id="' + id + '" style="display:none;"></iframe>').appendTo(_getBody());
            setTimeout(function () {
                _this.isIniting = false;
            },10);  
            var crossHelperPage = _this.crossHelperPage;
            var isCross = _this.isCross;           
            if(isCross){
                if(!crossHelperPage){
                    var links = $("head").children("link");
                    if(links.length === 1){
                        crossHelperPage = links.first().attr("href");
                    }else{
                        crossHelperPage = links.eq(2).attr("href");
                    }
                }
            }       
            ifr.on("load", function (e) {
                if (_this.isIniting) {
                    return;
                }
                clearInterval(ifr.data("timeoutchker"));
                _this.uploading = false;                
                var i = 0,
                    len = uploadFileArray.length;
                var callBakFn,
                    message,
                    json ,
                    res,
                    isSuccess = true;
                if(isCross){//跨域
                    if(!ifr.attr("src")){ 
                        try{
                            ifr[0].src = crossHelperPage;
                        }catch(ex1){
                        }
                        return;
                    }else{
                        try {                             
                            ifr.removeAttr("src");
                            res = ifr[0].contentWindow.name;
                            json = eval("(" + res + ")");
                        } catch (e1) {
                            isSuccess = false;
                            message = $B.config.uploadFail;
                            callBakFn = _this.error;
                        }
                    }
                }else{
                    try {                    
                        var ifrDoc = ifr[0].contentWindow.document || ifr[0].contentDocument;
                        var body = $(ifrDoc.body);                        
                        // body.children().remove();
                        res = body.text();
                        json = eval("(" + res + ")");
                    } catch (e1) {
                        isSuccess = false;
                        message = $B.config.uploadFail;
                        callBakFn = _this.error;
                        console.log("to json err "+res);
                    }
                }
                if(json){
                    if (json.code !== 0) {
                        isSuccess = false;
                        callBakFn = _this.error;
                        message = $B.config.uploadFail;
                        if (json.message && json.message !== "") {
                            message = json.message;
                        }
                    } else {
                        callBakFn = _this.success;
                    }
                }
                while (i < len) {
                    var vInput = uploadFileArray[i];
                    var $a = vInput.next().removeClass("k_update_close_disable");
                    if (isSuccess) {
                        vInput.html(vInput.attr("title"));
                        $a.children("i").attr("class","fa fa-check-1");
                    } else {
                        vInput.html(message);
                    }
                    i++;
                }
                if (typeof callBakFn === "function") {
                    callBakFn.call(uploadFileArray, json);
                }
                ifr.remove();
                uploadFileArray = undefined;
            });       
            return {
                id: id,
                ifr: ifr
            };
        },
        _changeFn: function (e) {
            var _this = e.data._this;
            var input = $(this);
            var v = input.val();
            var vInput = input.next("div");
            var accept = input.attr("accept").toLowerCase();
            vInput.next("a").children("i").attr("class","fa fa-cancel-2").attr("_class","fa fa-cancel-2");
            var must = input.attr("must");
            var isGoon = true;
            if (must && v === "") {
                vInput.html(must);
                return false;
            }
            var strFileName = v.replace(/^.+?\\([^\\]+?)(\.[^\.\\]*?)?$/gi, "$1$2");
            var srcFileName = strFileName;
            var label = input.attr("label");
            var name = input.attr("name");
            if (accept !== '.*') {
                var suffix = srcFileName.replace(/.+\./, "").toLowerCase();
                if (accept.indexOf(suffix) < 0) {
                    input.val("");
                    var acceptMsg = $B.config.uploadAccept.replace("<accept>", accept);
                    if ($B.alert) {
                        $B.alert({
                            width: 300,
                            height: 120,
                            message: acceptMsg,
                            timeout: 2
                        });
                        vInput.html(label);
                    } else {
                        vInput.html(acceptMsg);
                    }
                    return;
                }
            }
            if (strFileName === "") {
                strFileName = label;
            }
            if (typeof _this.onselected === 'function') {
                if (!_this.onselected.call(input, srcFileName, name, accept)) {
                    input.val("");
                    vInput.html(label);
                    isGoon = false;
                }
            }
            if (isGoon) {
                vInput.attr("title", strFileName).html(strFileName);
                if (_this.immediate) { //是否立即上传
                    var others = vInput.parent().siblings("div");
                    var othersInput = others.find("input[type=file]");
                    othersInput.hide().attr("disabled", "disabled");
                    _this.submit();
                    othersInput.show().removeAttr("disabled");
                }
            }
        },
        _createFileInput: function (file) {           
            var must = file.must ? "must=" + file.must : "";
            var it = $('<div class="k_upload_file_item_wrap k_box_size" style="width:auto;max-width: 100%; "></div>').appendTo(this.form);
            $('<input ' + must + ' label="' + file.label + '" id="' + file.name + '" name="' + file.name + '" type="file" accept="' + file.type + '" style="width:100%;">').appendTo(it);
            var vinput = $('<div title="' + file.label + '" class="k_visual_file_item_input k_box_size">' + file.label + '</div>').appendTo(it);
            this._bindFileEvents(vinput);
            var _this = this;
            var $a = $("<a class='k_upload_file_item_delete' title='" + $B.config.clearFile + "'><i class='fa fa-cancel-2'></i></a>").appendTo(it);
            $a.click(function () {
                var $t = $(this);
                if ($t.hasClass("k_update_close_disable")) {
                    return false;
                }
                var $vInput = $t.prev();
                var $input = $vInput.prev();
                var id = $input.attr("id");
                var label = $input.attr("label");
                var $itWrap = $t.parent();
                if ($itWrap.attr("d")) {
                    $B.confirm({
                        width: 280,
                        height: 125,
                        message: $B.config.uploadClearConfirm,
                        okText: $B.config.uploadClear,
                        noText: $B.config.uploadRemove,
                        noIcon: 'fa-trash',
                        okIcon: 'fa-cancel-circled',
                        okFn: function () {
                            if (typeof _this.ondeleted === "function" && $input.val() !== "") {
                                _this.ondeleted(id);
                            }
                            $vInput.html(label).attr("title", label);
                            $input.val("");
                            $vInput.next("a").children("i").attr("class","fa fa-cancel-2").attr("_class","fa fa-cancel-2");
                        },
                        noFn: function () {
                            $itWrap.prev("br").remove();
                            $itWrap.remove();
                            if (typeof _this.ondeleted === "function") {
                                _this.ondeleted(id);
                            }
                        }
                    });
                } else {
                    if (typeof _this.ondeleted === "function" && $input.val() !== "") {
                        _this.ondeleted(id);
                    }
                    $vInput.html(label).attr("title", label);
                    $input.val("");
                    $vInput.next("a").children("i").attr("class","fa fa-cancel-2").attr("_class","fa fa-cancel-2");
                }
            }).mouseover(function(){//
                var $t = $(this).children("i");
                var _class = $t.attr("class");
                $t.attr("class","fa fa-cancel-2").attr("_class",_class);
            }).mouseout(function(){
                var $t = $(this).children("i");
                var _class = $t.attr("_class");
                $t.attr("class",_class);
            });
            return it;
        },
        _bindFileEvents: function (vinput) {
            var _this = this;
            vinput.on("click", function () {
                var $v = $(this);
                var $_iput = $v.prev("input");
                if ($v.siblings("a").hasClass("k_update_close_disable")) {
                    return false;
                }
                $_iput.unbind("change").val("").on("change", {
                    _this: _this
                }, _this._changeFn);
                $_iput.trigger("click");
            });
        },
        submit: function () {
            //不是立即上传，外部手动上传
            if (!this.immediate && this.uploading) {
                console.log("is uploading ，donot submit！");
                return;
            }
            this.uploading = true;
            clearTimeout(this.tipTimer);
            var uploadingArray = [];
            var emptyFiles = [];
            var go2submit = false;
            var fileNames = [];
            this.form.children(".k_upload_file_item_wrap").each(function () {
                var $it = $(this);
                var input = $it.children("input");
                if (input.attr("disabled")) {
                    return true;
                }
                var vInput = input.next();
                var a = vInput.next();                
                if (input.val() === "" && input.attr("must")) {
                    vInput.html("<span style='color:#FFBCBF'>" + $B.config.uploadNotEmpty + "</span>");
                    emptyFiles.push(vInput);
                } else {
                    vInput.html("<span style='color:#fff'><i style='color:#fff' class='fa fa-spinner fa-spin'></i>" + $B.config.uploading + "</span>");                    
                    a.addClass("k_update_close_disable");
                    uploadingArray.push(vInput);
                    go2submit = true;
                    fileNames.push(input.attr("id"));
                }
            });
            if (go2submit) {
                this.form.children("input[type=hidden]").remove();
                if (typeof this.setParams === "function") {
                    var prs = this.setParams.call(this,fileNames);
                    if ($.isPlainObject(prs)) {
                        var keys = Object.keys(prs),
                            key;
                        for (var i = 0, len = keys.length; i < len; ++i) {
                            key = keys[i];
                            this.form.append("<input type='hidden' name='" + key + "' id='" + key + "' value='" + prs[key] + "'/>");
                        }
                    }
                }
                var _this = this;
                var ret = this._createIframe(uploadingArray);
                _this.isIniting = false;
                var ifrId = ret.id;
                //避免缓存问题
                var url = this.url;
                if(url.indexOf("?") > 0){
                    url = url +"&_t_="+$B.generateMixed(5);
                }else{
                    url = url +"?_t_="+$B.generateMixed(5);
                }
                this.form.attr("target", ifrId);
                this.form.attr("action", url);
                var startTime = new Date();
                this.form[0].submit();               
                var ivt = setInterval(function () {
                    var endTime = new Date();
                    var diff = getDateDiff(startTime, endTime);
                    if (diff > _this.timeout) {
                        _this.uploading = false;
                        clearInterval(ret.ifr.data("timeoutchker"));
                        ret.ifr.remove();
                        ret = undefined;
                        for (var j = 0, jlen = uploadingArray.length; j < jlen; ++j) {
                            uploadingArray[j].html($B.config.uploadTimeout);
                            uploadingArray[j].siblings("a").removeClass("k_update_close_disable");
                        }
                    }
                },1500);
                ret.ifr.data("timeoutchker", ivt);
            } else {
                this.uploading = false;
            }
            this.tipTimer = setTimeout(function () {
                for (var i = 0, len = emptyFiles.length; i < len; ++i) {
                    emptyFiles[i].html(emptyFiles[i].attr("title"));
                }
            }, 1000);
        },
        /***
         * file = {
                    name: 'xmlfile',
                    type: '.xml',
                    label: '请选择xml文件请选择xml文件请选择xml文件',
                    must: '必须上传文件!'
                }
         * **/
        addFile: function (file) {
            if (this.form.children(".k_upload_file_item_wrap").length > 0) {
                this.form.append("<br/>");
            }
            var it = this._createFileInput(file);
            it.attr("d", 1);
        },
        reset: function () {
            this.form.children(".k_upload_file_item_wrap").each(function () {
                    var $it = $(this);
                    var input = $it.children("input");
                    input.val("");
                    var label = input.attr("label");
                    var vInput = $it.children("div");
                    vInput.html(label).attr("title", label);
                    var $i = $it.children("a").removeClass("k_update_close_disable").children("i");
                    $i.removeClass("fa-check-1").addClass("fa-cancel-2");
            });
        }
    };

    $B["MutilUpload"] = MutilUpload;

    /***
     * xls导出封装
     * ***/
    $B.xlsDown = function (args) {
        args.target.children().remove();
        var date = new Date();
        var finish_down_key = date.getDay() + '' + date.getHours() + '' + date.getMinutes() + '' + date.getSeconds() + '' + date.getMilliseconds() + $B.generateMixed(6);
        var _this = this;
        var MyInterval = null;
        var $ifr = $('<iframe name="k_file_d_hiden_iframe_" id="k_file_d_hiden_iframe_id" style="display: none"></iframe>').appendTo(args.target);
        var ifr = $ifr[0];
        var _url = args.url;
        if (_url.indexOf("?") > 0) {
            _url = _url + "&isifr=1&_diff=" + $B.generateMixed(4);
        } else {
            _url = _url + "?isifr=1&_diff=" + $B.generateMixed(4);
        }
        var $msg = $("<h3 id='k_file_export_xls_msg_'  style='height:20px;line-height:20px;text-align:center;padding-top:12px;'><div class='loading' style='width:110px;margin:0px auto;'>正在导出......</div></h3>").appendTo(args.target);
        var $form = $('<form action="' + _url + '" target="k_file_d_hiden_iframe_" method="post" ></form>').appendTo(args.target);
        $form.append('<input type="hidden" id="fileName" name="fileName" value="' + encodeURIComponent(args.fileName) + '"/>');
        $form.append('<input type="hidden" id="sheetName" name="sheetName" value="' + encodeURIComponent(args.sheetName) + '"/>');
        $form.append('<input type="hidden" id="k_finish_down_key_" name="k_finish_down_key_" value="' + finish_down_key + '"/>');
        var isModel = 0;
        if ($.isPlainObject(args.model)) {
            isModel = 1;
            $form.append('<input type="hidden" id="modelfile" name="modelfile" value="' + encodeURIComponent(args.model.file) + '"/>');
            $form.append('<input type="hidden" id="startrow" name="startrow" value="' + args.model.startRow + '"/>');
        }
        $form.append('<input type="hidden" id="ismodel" name="ismodel" value="' + isModel + '"/>');
        if(_url.indexOf("cmd=") < 0){
            $form.append('<input type="hidden" id="cmd" name="cmd" value="exportXls"/>');
        }        
        /******补充上额外的参数******/
        if ($.isPlainObject(args.params)) {
            Object.keys(args.params).forEach(function (p) {
                var v = args.params[p];
                $form.append('<input type="hidden" id="' + p + '" name="' + p + '" value="' + encodeURIComponent(v) + '"/>');
            });
        }
        $form[0].submit();
        var regex = /(\/\w+)/g;
        var match, lastChar;
        do {
            match = regex.exec(args.url);
            if (match !== null) {
                lastChar = match[0];
            }
        } while (match !== null);
        var url = args.url.replace(lastChar, "/checkFileCreate");
        if (url.indexOf("?") > 0) {
            url = url + '&k_finish_down_key_=' + finish_down_key;
        } else {
            url = url + '?k_finish_down_key_=' + finish_down_key;
        }
        var ivtTime = 2000;
        if (args.ivt) {
            ivtTime = args.ivt;
        }
        var inteVal = setInterval(function () {
            try {
                var _$body = $(window.frames["k_file_d_hiden_iframe_"].document.body);
                // _$body.children().remove();
                var res = _$body.text();
                if (res && res !== '') {
                    clearInterval(inteVal);
                    var json = eval("(" + res + ")");
                    $msg.html("<h2>" + json.message + "</h2>");                    
                    return;
                }
            } catch (e) {
                clearInterval(inteVal);
                $msg.html("<h2>" + $B.config.expException + "</h2>");
                return;
            }
            $B.request({
                url: url + "&_t=" + $B.generateMixed(5),
                ok: function (res, data) {
                    if (res !== 'null') {
                        clearInterval(inteVal);
                        $msg.html(res);
                        if (typeof args.success === 'function') {
                            setTimeout(function () {
                                args.success(res);
                            }, 10);
                        }
                    }
                }
            });
        }, ivtTime);
    };
    return MutilUpload;
}));(function (global, factory) {
	if (typeof define === 'function' && define.amd) {
		define(['$B', "config"], function (_$B) {
			return factory(global, _$B);
		});
	} else {
		if(!global["$B"]){
            global["$B"] = {};
        }
        factory(global, global["$B"]);
	}
}(typeof window !== "undefined" ? window : this, function (window, $B) {
	var DEFMSG = $B.config.valid.message;
	var REGEX = $B.config.valid.regex;	
	/**事件绑定***/
	function bindEvent($t, _this) {
		var objEvt = $._data($t[0], "events");
		if (objEvt && objEvt["click"] && objEvt["mouseout"] && objEvt["keyup"]) {
			return;
		}
		$t.on({
			click: function () {
				var $t = $(this);
				$t.siblings('.k_validate_tip_wrap').remove();
				$t.removeClass("k_input_value_err");
				if (_this.onTipFn) {
					_this.onTipFn.call($t, "");
				}
			},
			keyup: function () {
				var $t = $(this);
				var res = v($t, _this);
				if (res) {
					$t.siblings('.k_validate_tip_wrap').remove();
					$t.removeClass("k_input_value_err");
				}
			}
		});	
		$t.on("mouseleave.kvalidate",function (e) {			
			v($(this), _this);
		});	
	}
	/**
	 * 远程验证！
	 * ***/
	function remote(r, $this, $tip) {
		clearTimeout($this.data("remote_req_timer"));
		var timer = setTimeout(function(){
			var txt = $this.val();
			var id = $this.attr("id");
			if(!id || id === ""){
				id = $this.attr("name");
			}
			if (txt !== "") {
				var prs = {};
				prs[id] = txt;
				var url = r.rule["remote"];
				var opts = {
					url: url,
					data: prs,
					ok: function (res) {									
						var msg;
						if (typeof res === "string" && res !== "") {					
							msg = res;						
						}else if($.isPlainObject(res) && res.code === 1){					
							msg = res.message;
						}
						if(msg){
							var char_w = $B.getCharWidth(msg);
							var $wrap = $this.parent();
							$tip.appendTo($wrap).children(".k_validate_tip_content").width(char_w).html(msg);
							$this.addClass("k_input_value_err");
							var _pos = $tip.position();
							if ((char_w + _pos.left) > $wrap.width()) {
								$tip.css({
									left: 0,
									top: _pos.top - $wrap.height()
								});
								setTimeout(function () {
									$tip.remove();
								}, 2000);
							}
						}
					},
					fail: function (res) {}
				};
				$B.request(opts);
			}
		},800);
		$this.data("remote_req_timer" , timer);	
	}

	function a(r, txt, _this) {
		var rs = [];
		if ($.isPlainObject(r.rule)) {
			var p = true;
			var t = typeof r.rule["regex"];
			if (t !== 'undefined') {
				var re = null;
				try {
					if (t === 'string') {
						re = new RegExp(r.rule["regex"], "i");
					} else {
						re = r.rule["regex"];
					}
				} catch (e) {}
				if (re !== null && txt !== "" && !re.test(txt)) {
					rs.push(typeof r.msg === 'undefined' ? DEFMSG['regex'] : r.msg);
				}
			}
			if (typeof r.rule["minlength"] !== 'undefined') {
				if (txt !== "") {
					//if (txt.replace(/[^\x00-\xff]/gi, "--").length < r.rule["minlength"]) {
					if (txt.length < r.rule["minlength"]) {
						rs.push(typeof r.msg === 'undefined' ? DEFMSG['minlength'].replace('{1}', r.rule["minlength"]) : r.msg);
					}
				}
			}
			if (typeof r.rule["maxlength"] !== 'undefined') {
				if (txt !== "") {
					if (txt.length > r.rule["maxlength"]) {
					//if (txt.replace(/[^\x00-\xff]/gi, "--").length > r.rule["maxlength"]) {
						rs.push(typeof r.msg === 'undefined' ? DEFMSG['maxlength'].replace('{1}', r.rule["maxlength"]) : r.msg);
					}
				}
			}
			if (typeof r.rule["range"] !== 'undefined') {
				var tmp = r.rule["range"];
				var min = tmp[0],
					max = tmp[1];
				if (txt !== "") {
					if (REGEX.number.test(txt)) {
						var i = parseInt(txt);
						if (i < min || i > max) {
							rs.push(typeof r.msg === 'undefined' ? DEFMSG['range'].replace('{1}', min).replace('{2}', max) : r.msg);
						}
					} else {
						rs.push("只能输入数字文本！");
					}
				}
			}
		} else {
			var ok = true;
			switch (r.rule) {
				case "url":
					if (txt !== "") {
						if (!REGEX.url.test(txt)) {
							ok = false;
						}
					}
					break;
				case "require":
					if (txt === "") {
						ok = false;
					}
					break;
				case "email":
					if (txt !== "") {
						if (!REGEX.email.test(txt)) {
							ok = false;
						}
					}
					break;
				case "number":
					if (txt !== "") {
						if (!REGEX.number.test(txt)) {
							ok = false;
						}
					}
					break;
				case "digits":
					if (txt !== "") {
						if (!REGEX.digits.test(txt)) {
							ok = false;
						}
					}
					break;
				case "phone":
					if (txt !== "") {
						if (!REGEX.phone.test(txt)) {
							ok = false;
						}
					}
					break;
				case "chchar":
					if (txt !== "") {
						if (REGEX.chchar.test(txt)) {
							ok = false;
						}
					}
					break;
				case "wchar":
					if (txt !== "") {
						if (!REGEX.wchar.test(txt)) {
							ok = false;
						}
					}
					break;
				case "telphone":
					if (txt !== "") {
						if (!REGEX.telphone.test(txt)) {
							ok = false;
						}
					}
					break;
				case "enchar":
					if (txt !== "") {
						if (!REGEX.enchar.test(txt)) {
							ok = false;
						}
					}
					break;
			}
			if (!ok) {
				rs.push(typeof r.msg === 'undefined' ? DEFMSG[r.rule] : r.msg);
			}
		}
		return rs;
	}

	function v($this, _this) {
		//console.log("valid >>>>>>>>>");
		var ok = true;
		var $wrap = $this.parent().css("position", "relative");
		var this_pos = $this.position();
		var w = $this.outerWidth() + 1;
		var h = $this.outerHeight() - 2;
		var pos = {
			top: this_pos.top + 3 + "px",
			left: (this_pos.left + w) + "px"
		};		
		var id = $this.attr("id");
		if(!id || id === ""){
			id = $this.attr("name");
		}
		var clsId = "validate_" + id;
		$wrap.children("." + clsId).remove();
		var $tip = $("<div class='k_validate_tip_wrap " + clsId + "'><div class='k_validate_tip_top'></div><div class='k_validate_tip_content'></div></div>").css(pos);
		var rule = _this.rules[id];
		if ($.isPlainObject(rule) || $.isArray(rule)) {
			var txt;
			if ($this.tagName === 'textarea') {
				txt = $.trim($this.val());
			} else {
				txt = $.trim($this.val());
			}
			/**
			 * 下拉复选框情况
			 * ***/
			if ($this.hasClass("k_combox_input")) {
				txt = $this.data("id");
			}
			if ($.isArray(rule)) { //如果一个标签是多个验证规则    
				var remoteRule = null;
				var old_id, oldCompare, go;
				$.each(rule, function () {				
					if ($.isPlainObject(this["rule"]) && typeof this["rule"]["remote"] !== 'undefined') {
						remoteRule = this;
					} else {
						var res = a(this, txt, _this);
						if (res.length > 0) {							
							ok = false;
							var strtip = res.join("");
							if (_this.onTipFn && strtip !== "") {
								_this.onTipFn.call($this, strtip);
							} else {
								var char_w = $B.getCharWidth(strtip);
								if (char_w > w) {
									char_w = w;
								}
								if ($this.hasClass("k_combox_input")) {
									$wrap = $wrap.parent().css("position","relative");
								}
								var tmpTip = $wrap.children(".k_validate_tip_wrap");
								if(tmpTip.length > 0){
									$tip = tmpTip.children(".k_validate_tip_content").width(char_w).html(strtip);
								}else{
									$tip.appendTo($wrap).children(".k_validate_tip_content").width(char_w).html(strtip);
								}
								var _pos = $tip.position();
								var wrapWidth = $wrap.width();
								if ((char_w + _pos.left) > wrapWidth) {
									$tip.css({
										left: 0,
										top: _pos.top - $wrap.height()
									});
									setTimeout(function () {
										$tip.remove();
									}, 2000);
								}
							}
						} else {
							if (_this.onTipFn) {
								_this.onTipFn.call($this, "");
							}
						}
					}
				});
				if (ok && remoteRule !== null) {
					old_id = "#old_" + id;
					oldCompare = _this.form.find(old_id);
					go = true;
					if (oldCompare.length > 0) {
						if (oldCompare.val() === txt) {
							go = false;
						}
					}
					if (go) {
						remote(remoteRule, $this, $tip);
					}
				}
			} else {
				if (typeof rule["remote"] !== 'undefined') {
					old_id = "#old_" + id;
					oldCompare = _this.form.find(old_id);
					go = true;
					if (oldCompare.length > 0) {
						if (oldCompare.val() === txt) {
							go = false;
						}
					}
					if (go) {
						remote(rule, $this, $tip);
					}
				} else {
					var res = a(rule, txt, _this);
					if (res.length > 0) {
						ok = false;
						var strtip = res.join("");
						if (_this.onTipFn && strtip !== "") {
							_this.onTipFn.call($this, strtip);
						} else {
							var char_w = $B.getCharWidth(strtip);
							if (char_w > w) {
								char_w = w;
							}
							$tip.appendTo($wrap).children(".k_validate_tip_content").width(char_w).html(strtip);
							var _pos = $tip.position();
							if ((char_w + _pos.left) > $wrap.width()) {
								$tip.css({
									left: 0,
									top: _pos.top - $wrap.height()
								});
								setTimeout(function () {
									$tip.remove();
								}, 1500);
							}
						}
					} else {
						if (_this.onTipFn) {
							_this.onTipFn.call($this, "");
						}
					}
				}
			}
		}
		$this.attr("valid", ok);
		if(ok){//验证通过
			var $p = $this.parent();
			if($this.hasClass("k_combox_input")){
				$p = $p.parent();
			}
			$p.children(".k_validate_tip_wrap").remove();
			$this.removeClass("k_input_value_err");
		}else{
			$this.addClass("k_input_value_err");
		}
		return ok;
	}
	/******
	 * 构造函数
	 * @param args:验证规则集合
	 * @param form:包含被验证元素的容器(jquery对象)，可有，可无。无的时候，手工调用valid验证时传入即可
	 * *******/
	$B.Validate = function (args, form ,onTipFn) {
		this.rules = args;
		if (form) {
			this.form = form;
			this.findFormTag(this.form);
		}
		if(onTipFn){
			this.onTipFn = onTipFn;
		}
	};
	$B.Validate.prototype.setTipFn = function (fn) {
		this.onTipFn = fn;
	};
	$B.Validate.prototype.deleteRule = function (filedName) {
		if (this.rules) {
			delete this.rules[filedName];
		}
	};
	$B.Validate.prototype.addRule = function (filedName, newRules) {
		if (!this.rules) {
			this.rules = {};
		}
		this.rules[filedName] = newRules;
	};
	$B.Validate.prototype.valid = function (form) {
		if (!this.form && typeof form === 'undefined') {
			alert("验证组件必须传入表单对象！");
			return false;
		}
		if (!this.form) {
			this.form = form;
		}
		var _this = this;
		var allTag = this.findFormTag(this.form);
		var isPast = true;
		$.each(allTag, function () {
			var tmp = v(this, _this);
			if (!tmp) {
				isPast = false;
			}
		});
		return isPast;
	};
	$B.Validate.prototype.findFormTag = function (f) {
		var _this = this;
		var allTag = [];
		var allText = f.find("input[type=text]");
		allText.each(function () {
			var $t = $(this);
			bindEvent($t, _this);
			allTag.push($t);
		});
		var allPwdText = f.find("input[type=password]");
		allPwdText.each(function () {
			var $t = $(this);
			bindEvent($t, _this);
			allTag.push($t);
		});
		var allFileText = f.find("input[type=file]");
		allFileText.each(function () {
			var $t = $(this);
			bindEvent($t, _this);
			allTag.push($t);
		});
		var allAreatext = f.find("textarea");
		allAreatext.each(function () {
			var $t = $(this);
			bindEvent($t, _this);
			allTag.push($t);
		});
		var allSelect = f.find("select");
		allSelect.each(function () {
			var $t = $(this);
			bindEvent($t, _this);
			allTag.push($t);
		});
		return allTag;
	};
	return $B.Validate;
}));(function (global, factory) {
    if (typeof define === 'function' && define.amd) {
        define(['$B'], function (_$B) {
            return factory(global, _$B);
        });
    } else {
        if (!global["$B"]) {
            global["$B"] = {};
        }
        factory(global, global["$B"]);
    }
}(typeof window !== "undefined" ? window : this, function (window, $B) {
    var defOpts = {
        textField: 'text',
        ellipsis:false,
        idField: 'id',
        scrollStyle:{
            size: '8px',
            display:'auto',
            setPadding:false,
            hightColor:"#1590FA",
            slider: {
                "background-color": '#6CB7FA',
                "border-radius": "8px",
            },bar:{
                "background-color": "#E8E8E8",
                "border-radius": "8px",
                "opacity": 0.5
            }   
        }
    };
    /***
   *opts = {
       data: null, //'数据'       
       textField: 'text', //菜单名称字段，默认为text
       idField: 'id', //菜单id字段,默认为id
       onClick:fn(data)    		
   }
   ****/
    function Menu(jqObj, opts) {
        $B.extend(this, Menu); //继承父类        
        this.jqObj = jqObj.addClass("k_box_size k_menu_wrap").css({       
            "height": "100%",
            "width": "100%",
            "overflow": "visible"
        });
        this.scrollWrap = $("<div style='height:100%;width:100%;padding-right:0px;padding-bottom:2px;' class='k_menu_wrap_scroll k_box_size'></div>").appendTo(this.jqObj);
        this.treeWrap = $("<div class='k_menu_wrap_ul clearfix' ></div>").appendTo(this.scrollWrap);      
        this.opts = $.extend(true,{} , defOpts, opts);
        var datas = this.opts.data;
        var vDom = $("<div/>");
        this.firstItem = undefined;
        this._createList(vDom, datas, 1);
        this.maxWidth = 0;
        vDom.children().detach().appendTo(this.treeWrap);        
        if (this.firstItem) {
            this.firstItem.trigger("click");
        }
        this.scrollObj = this.scrollWrap.myscrollbar(this.opts.scrollStyle).getMyScrollIns();
        this._setWrapWidth();
        this._setMinWidth();
        var _this = this;
        var nsId = $B.getUUID();
        $(window).on("resize."+nsId,function(){
            if(_this._setMinWidth){
                _this._setMinWidth();
            }else{
                $(this).off("."+nsId);
            }
        });
    }
    Menu.prototype = {
        _setMinWidth:function(){
            var minWidth = this.treeWrap.parent().width();            
            if(this.opts.ellipsis){
                this.rootUl.css("width",minWidth);
            }else{
                this.rootUl.css("min-width",minWidth);
            }
        },
        _itClickEnvent: function (e) {
            var _this = e.data._this;
            var $a = $(this);
            var mdata = $a.data("mdata");
            var isParent = typeof mdata.children !== 'undefined';
            if (isParent) {
                var $ul = $a.next("ul").slideToggle("fast", function () {
                    var $icon = $a.children(".k_menu_parent_icon");
                    if ($ul.css("display") === "none") {
                        $icon.removeClass("fa-angle-down").addClass("fa-angle-left").css("padding-right","6px");
                    } else {
                        $icon.removeClass("fa-angle-left").addClass("fa-angle-down").css("padding-right","3px");
                    }
                    _this._setWrapWidth();
                    _this.scrollObj.resetSliderPosByTimer();
                });
            }
            if (_this.opts.onClick) {
                setTimeout(function () {
                    _this.opts.onClick.call($a, mdata.data ? mdata.data : mdata, isParent);
                }, 10);
            }
            if (isParent) {
                return;
            }
            if (_this.activedItem) {
                _this.activedItem.removeClass("k_menu_actived");
            }
            _this.activedItem = $a.addClass("k_menu_actived");
        },
        _setWrapWidth:function(){           
            if(this.opts.ellipsis){
                this.treeWrap.width("100%");
            }else{
                this.treeWrap.width(this.rootUl.width());
            }
        },
        _createList: function (wrap, datas, deep) {
            var ul = $("<ul class='k_menu_ul' style='width:auto;'/>").appendTo(wrap);
            if(!this.opts.ellipsis){//,"float":"left"
                ul.css({"min-width" :"100%"});
            }
            if (deep === 1) {
               this.rootUl = ul.addClass("k_menu_ul_root");
            }
            for (var i = 0, len = datas.length; i < len; ++i) {
                var data = datas[i];
                var txt = data[this.opts.textField];
                var li = $("<li style='white-space: nowrap;width:auto;list-style:none;' ><a style='display:inline-block;white-space:nowrap;padding-right:10px;' class='k_box_size'>" + txt + "</a></li>").appendTo(ul);
                var $a = li.children("a");
                if(this.opts.ellipsis){
                    $a.css({"width":"100%" , "max-width" : "100%","text-overflow" :" ellipsis","overflow":"hidden","padding-right":"0px"});
                }else{
                    $a.css("min-width","100%");
                }
                $a.attr("title",txt);
                var icon = data.data.menuIconCss;               
                var r = 15;
                if (deep === 1) {
                    r = 12;
                }
                $a.css("padding-left", deep * r);
                if (icon && icon !== "") {
                    $a.prepend("<i style='padding-right:6px;' class='fa " + icon + "'><i>");
                }                
                if (data.children) {
                    $a.prepend("<i class='fa fa-angle-down k_menu_parent_icon'></i>");
                    // console.log("is parent >");
                    // if(this.opts.ellipsis){                       
                    // }else{
                    //     $a.prepend("<i class='fa fa-angle-down k_menu_parent_icon'></i>");
                    // }                    
                    this._createList(li, data.children, deep + 1);
                } else {
                    if (!this.firstItem) {
                        this.firstItem = $a;
                    }
                }
                $a.on("click", { _this: this }, this._itClickEnvent).data("mdata", data);
                if(this.opts.onItemCreated){
                    this.opts.onItemCreated.call(li,data, typeof data.children !== 'undefined');
                }
            }
        },
        _loopParent: function (txtArray, aEle) {
            var ul = aEle.parent().parent();
            if (!ul.hasClass("k_menu_ul_root")) {
                var ele = ul.prev("a");
                var txt = ele.data("mdata").text;
                txtArray.push(txt);
                this._loopParent(txtArray, ele);
            }
        },
        getTreeTxtPath: function () {
            var item = this.activedItem;
            var arr = [];
            var txt = item.data("mdata").text;
            arr.push(txt);
            this._loopParent(arr, item);
            return arr.reverse();
        },
        destroy:function(){          
            this.scrollObj.destroy();
            this.super.destroy.call(this);
        }
    };
    $B["Menu"] = Menu;
    return Menu;
}));/***
 * 2019-05-03 
 * 支持通过input标签的value值初始化
 * ****/
(function (global, factory) {
    if (typeof define === 'function' && define.amd) {
        define(['$B'], function (_$B) {
            return factory(global, _$B);
        });
    } else {
        if (!global["$B"]) {
            global["$B"] = {};
        }
        factory(global, global["$B"]);
    }
}(typeof window !== "undefined" ? window : this, function (window, $B) {
    var $body;
    function _getBody() {
        if (!$body) {
            $body = $(window.document.body).css("position", "relative");
        }
        return $body;
    }
    var def = {
        show: false,
        fixed: false,//是否固定显示
        fitWidth: false, //是否将input宽度和 控件宽度调整一致
        initValue: undefined, //可以是date对象，可以是字符串
        shadow: true,//是否需要阴影
        fmt: 'yyyy-MM-dd hh:mm:ss',
        mutil: false,
        clickHide: false,
        readonly: true,
        isSingel: false, //是否是单列模式
        //时间日期选择范围定义,min/max = now / inputId ,'yyyyy-MM-dd hh:mm:ss' 
        range: { min: undefined, max: undefined },
        onChange: undefined //onChange = function(date){}
    };
    function MyDate(jqObj, opts) {
        $B.extend(this, MyDate);    
        jqObj.addClass("k_calendar_input");
        if (opts.fitWidth) {
            jqObj.addClass("k_box_size").outerWidth(202);
        }
        var value = jqObj.val();
        if(value !== ""){
            var  currentDate = this._txt2Date(value);
            if(currentDate){
                opts.initValue = value;
            }
        }
        if (opts.isSingel) {
            jqObj.data("_calopt", { range: opts.range, onChange: opts.onChange, initValue: opts.initValue });
            opts.fixed = false;
            opts.show = false;
            var ins = window["_k_calendar_ins_"];
            if (ins) {
                ins.setTarget(jqObj, true);
                return ins;
            } else {
                window["_k_calendar_ins_"] = this;
            }
        }
        var config = $B.config.calendar;
        this.config = config;
        this.target = jqObj;
        var i, len, _this = this;
        this.opts = $.extend({}, def, opts);
        this.isMonthStyle = this.opts.fmt === "yyyy-MM";
        this.isDayStyle = this.opts.fmt === "yyyy-MM-dd";
        this.isSecondStyle = this.opts.fmt === "yyyy-MM-dd hh:mm:ss";
        $B.extend(this, MyDate); //继承父类 
       
        this.currentDate = new Date();//默认初始化当前时间          
        this._initValue(true);
        this._bindInputEvents();
        this.jqObj = $("<div class='k_calendar_wrap k_box_size clearfix' style='width:202px;z-index:200000000;'></div>");
        if (this.opts.shadow) {
            this.jqObj.addClass("k_dropdown_shadow");
        }
        if (this.opts.fixed) {//固定显示
            this.opts.show = true;
        }
        if (!this.opts.show) {
            this.jqObj.hide();
        }
        /**顶部工具栏**/
        this.headerPanel = $("<div class='k_calendar_pannel k_box_size clearfix' style='padding-left:2px;padding-top:2px;'><span class='_prev_year _event' style='width:24px'><i class='fa fa-angle-double-left'></i></span><span  style='width:21px' class='_prev_month _event'><i class='fa fa-angle-left'></i></span><span class='_cur_year  _event' style='width:46px;'>" + this.year + "</span><span>" + config.year + "</span><span class='_cur_month _event' style='width:28px;' >" + this.month + "</span><span>" + config.month + "</span><span style='width:25px' class='_next_month _event'><i class='fa fa-angle-right'></i></span><span class='_next_year _event' style='width:24px'><i class='fa fa-angle-double-right'></i></span></div>").appendTo(this.jqObj);
        this.bindHeaderPanelEvents();

        /**周**/
        this.weekPanel = $("<div class='k_calendar_week k_box_size' style='padding-left:2px;margin-bottom:5px;'></div>");
        for (i = 0, len = config.weekArray.length; i < len; ++i) {
            $("<span class='k_calendar_week_day'>" + config.weekArray[i] + "</span>").appendTo(this.weekPanel);
        }
        this.weekPanel.appendTo(this.jqObj);

        /**天列表**/
        this.daysPanel = $("<div class='k_calendar_days k_box_size clearfix' style='padding-left:2px;'></div>").appendTo(this.jqObj);
        this.createDays();

        /**时间***/
        this.timePanel = $("<div class='k_calendar_time k_box_size' style='margin:1px 0px;padding-left:2px;text-align:center;'></div>").appendTo(this.jqObj);
        this.createTimeTools();

        /***工具栏***/
        this.toolPanel = $("<div class='k_calendar_bools k_box_size clearfix' style='padding-left:1px;'></div>").appendTo(this.jqObj);
        this.createTools();

        this.setPosition();
        if (this.isDayStyle) {
            this.timePanel.hide();
        }
        if (this.isMonthStyle) {//月模式
            this.daysPanel.hide();
            this.timePanel.hide();
            this.headerPanel.children("._cur_month").trigger("click");
            this.toolPanel.css("margin-top", "168px");
        }
        this.jqObj.appendTo(_getBody());
        var nsId = $B.getUUID();
        $(document).on("click."+nsId,function(){
            if(_this.hide){
                _this.hide();
            }else{
                $(this).off("."+nsId);
            }            
        });
        $(window).on("resize."+nsId,function(){
            if(_this.setPositionByTimer){
                _this.setPositionByTimer();
            }else{                
                $(this).off("."+nsId);
            }            
        });
        _this._setBorderColor();
        this.target.data("calender",this);
    }
    MyDate.prototype = {
        /**
         * 根据输入框值 初始化currentDate  year、month变量 
         * isInit 是否是new 初始化调用
         * ***/
        _initValue: function (isInit) {
            var value = this.target.val().leftTrim().rightTrim();
            if (value !== "") {
                this.currentDate = this._txt2Date(value);
            }
            if (isInit) {
                var initVal = this.opts.initValue;
                if (this.opts.isSingel) {
                    initVal = this.target.data("_calopt").initValue;
                }
                //取 initValue
                if (initVal) {
                    if (typeof initVal === "string") {
                        this.currentDate = this._txt2Date(initVal);
                    } else {
                        this.currentDate = initVal;
                    }
                    this.target.val(this.currentDate.format(this.opts.fmt));
                }
            }
            this._setVarByDate(this.currentDate);
        },
        _bindInputEvents: function () {
            var _this = this;
            var binding = this.target.data("k_calr_ins") === undefined;
            if (this.opts.readonly) {
                this.target.attr("readonly", true);
            } else if (binding) {//启用了用户输入                          
                var onInputEvFn = function () {
                    var v = _this.target.val();
                    var inputDate = _this._txt2Date(v);
                    if (inputDate) {
                        if (_this._beforeChange(inputDate)) {
                            _this._setCurrentDate(inputDate);
                            _this._setVarByDate(inputDate);
                            _this.rebuildDaysUi();
                            _this.updateYearAndMonthUi(_this.currentDate);
                            if (_this.isMonthStyle) {//如果是月模式
                                _this._createMonthOpts();
                            } else {
                                _this._updateMinAndCec();
                            }
                            if(_this.onWatcher){//配合双向联动使用
                                _this.onWatcher.call(_this);
                            }
                        }
                    } else {
                        $B.error(_this.config.error, 2);
                        var srcVal = _this.currentDate.format(_this.opts.fmt);
                        _this.target.val(srcVal);
                    }
                };
                this.hasInputed = false;
                this.target.on("input", function () {
                    _this.hasInputed = true;
                    clearTimeout(_this.userInputTimer);
                    _this.userInputTimer = setTimeout(function () {
                        onInputEvFn();
                    },1000);
                });
            }
            if (binding) {
                this.target.on("blur", function () {
                    _this._setBorderColor();
                    if (_this.hasInputed) {
                        _this.hasInputed = false;
                        clearTimeout(_this.userInputTimer);
                        onInputEvFn();
                    }
                }).on("click", function () {
                    _this._setBorderColor();
                    if (!_this.opts.fixed) {
                        _this.slideToggle();
                    }
                    return false;
                }).on("focus", function () {
                    if (_this.opts.isSingel) {
                        _this.setTarget($(this), false);
                    }
                    _this._setBorderColor();
                });
                this.target.data("k_calr_ins", this);
                this.target.css("cursor", "pointer");
            }
        },
        _setBorderColor: function () {
            var borderColor = this.target.css("border-color");
            this.jqObj.css("border-color", borderColor);
        },
        _getMinMaxCfg: function (flag) {
            var _date, v;
            var range = this.opts.range;
            if (this.opts.isSingel) {
                range = this.target.data("_calopt").range;
            }
            if (range[flag]) {
                if (range[flag].indexOf("#") > -1) {
                    var input = this.target.data(flag + "_input");
                    if (!input) {
                        input = $(range[flag]);
                        this.target.data(flag + "_input", input);
                    }
                    v = input.val();
                    _date = this._txt2Date(v);
                } else if (range[flag] === "now") {
                    _date = new Date();
                } else {
                    v = range[flag];
                    _date = this._txt2Date(v);
                }
            }
            return _date;
        },
        /****
         * 最小值，最大值非法限制检查
         * ***/
        _legalDate: function (newDate, minDate, maxDate) {
            if (minDate) {
                if (newDate.getTime() < minDate.getTime()) {
                    return this.config.minTip.replace("x", minDate.format(this.opts.fmt));
                }
            }
            if (maxDate) {
                if (newDate.getTime() > maxDate.getTime()) {
                    return this.config.maxTip.replace("x", maxDate.format(this.opts.fmt));
                }
            }
            return "";
        },
        /**时间变更前回调
         * 如果不符合要求，调用this._setVarByDate(this.currentDate); 恢复变量
         * ***/
        _beforeChange: function (newDate) {
            var go = true;
            var minDate = this._getMinMaxCfg("min"),
                maxDate = this._getMinMaxCfg("max");
            var res = this._legalDate(newDate, minDate, maxDate);
            if (res !== "") {
                $B.alert(res, 2.5);
                go = false;
            }
            var changeFn = this.opts.onChange;
            if (this.opts.isSingel) {
                changeFn = this.target.data("_calopt").onChange;
            }
            if (go && typeof changeFn === "function") {
                res = changeFn(newDate, newDate.format(this.opts.fmt));
                if (typeof res !== "undefined" && res !== "") {
                    $B.alert(res, 2.5);
                    go = false;
                }
            }
            if (!go) {//this.currentDate没有被修改, 恢复被修改的变量
                this._setVarByDate(this.currentDate);
            }
            return go;
        },
        /**
         * 绑定顶部年/月改变事件
         * ***/
        bindHeaderPanelEvents: function () {
            var _this = this;
            var clickFn = function () {
                if (_this.hourItsPanel) {
                    _this.hourItsPanel.hide();
                }
                if (_this.mmItsPanel) {
                    _this.mmItsPanel.hide();
                }
                var $t = $(this);
                var newDate = _this._var2Date();//获取当前 this.currentDate的副本，用于加减运算
                var curDay = newDate.getDate();
                var update = true;
                if ($t.hasClass("_prev_year")) {
                    newDate.setFullYear(newDate.getFullYear() - 1);
                } else if ($t.hasClass("_prev_month")) {
                    //兼容有溢出的场景 先取上一个月最大日期
                    var lastMonthDate = new Date(newDate.getFullYear(), newDate.getMonth(), 0, _this.hour, _this.minutes, _this.seconds);
                    if (curDay < lastMonthDate.getDate()) {
                        lastMonthDate.setDate(curDay);
                    }
                    newDate = lastMonthDate;
                } else if ($t.hasClass("_cur_year")) {
                    _this._hideMonthPanel();
                    update = false; //
                    if (_this.yearPanel && _this.yearPanel.css("display") !== "none") {
                        _this.yearPanel.hide(100);
                    } else {
                        _this._createYearOpts(newDate.getFullYear());
                    }
                } else if ($t.hasClass("_cur_month")) {
                    if (_this.yearPanel) {
                        if (_this.isMonthStyle) {//月模式不可以关闭                           
                            return false;
                        }
                        _this.yearPanel.hide();
                    }
                    update = false;
                    if (_this.monthPanel && _this.monthPanel.css("display") !== "none") {
                        _this._hideMonthPanel(100);
                    } else {
                        _this._createMonthOpts();
                    }
                } else if ($t.hasClass("_next_month")) {
                    //需要考虑月溢出场景
                    var nextMonthDate = new Date(newDate.getFullYear(), newDate.getMonth() + 2, 0, _this.hour, _this.minutes, _this.seconds);
                    if (curDay < nextMonthDate.getDate()) {
                        nextMonthDate.setDate(curDay);
                    }
                    newDate = nextMonthDate;
                } else if ($t.hasClass("_next_year")) {
                    newDate.setFullYear(newDate.getFullYear() + 1);
                }
                if (update) {
                    if (_this.yearPanel) {
                        _this.yearPanel.hide();
                    }
                    _this._hideMonthPanel();
                    if (_this._beforeChange(newDate)) { //先调用日期时间变更
                        _this._updateVar(newDate);
                        if (!_this.opts.mutil) {//多选场景不需要更新输入框
                            _this.update2target(newDate);
                        }
                        _this.updateYearAndMonthUi(newDate);
                        _this.rebuildDaysUi(newDate);
                        if (_this.isMonthStyle) {//月模式
                            var curMonth = newDate.getMonth() + 1;
                            _this._activeMonthUi(curMonth);
                        }
                    }
                }
                return false;
            };
            var prevYear = this.headerPanel.children().first().click(clickFn);
            var prevMonth = prevYear.next().click(clickFn);
            var curyear = prevMonth.next().click(clickFn);
            var curMonth = curyear.next().next().click(clickFn);
            var nextMonth = curMonth.next().next().click(clickFn);
            nextMonth.next().click(clickFn);
        },
        /**年点击事件***/
        _yearOnclick: function (e) {
            var _this = e.data._this;
            var $t = $(this);
            var $i = $t.children("i");
            if ($i.length > 0) {
                var startYear;
                if ($i.hasClass("fa-angle-double-left")) {//
                    startYear = parseInt($t.siblings(".k_box_size").first().text()) - 18;
                } else {
                    startYear = parseInt($t.siblings(".k_box_size").last().text()) + 1;
                }
                var startTg = $t.parent().children(".k_box_size").first().next();
                while (startTg.length > 0 && startTg.hasClass("_year_num")) {
                    startTg.text(startYear);
                    if (startYear === _this.year) {
                        startTg.addClass("actived");
                    } else {
                        startTg.removeClass("actived");
                    }
                    startYear++;
                    startTg = startTg.next();
                }
            } else {
                var year = parseInt($t.text());
                _this.year = year;
                var newDate = _this._var2Date();
                if (_this._beforeChange(newDate)) {
                    _this._setCurrentDate(newDate);
                    _this.rebuildDaysUi();
                    _this.updateYearAndMonthUi(_this.currentDate);
                    if (!_this.opts.mutil) {
                        _this.update2target(_this.currentDate);
                    }
                    _this.yearPanel.hide(120);
                }
            }
            return false;
        },
        /**
         * 年选择列表
         * ***/
        _createYearOpts: function (year) {//创建年选项
            var append = false;
            if (this.yearPanel) {
                this.yearPanel.children(".k_box_size").remove();
                this.yearPanel.show();
            } else {
                append = true;
                var _this = this;
                this.yearPanel = $("<div class='k_box_size clearfix k_calendar_ym_panel k_dropdown_shadow' style='padding-left:12px;position:absolute;top:30px;left:0;z-index:2110000000;width:100%;background:#fff;'></div>").appendTo(this.jqObj);
                var $closed = $("<div style='position:absolute;top:-2px;right:5px;width:12px;height:12px;line-height:12px;text-align:center;cursor:pointer;'><i class='fa fa-cancel-2' style='font-size:14px;color:#AAAAB4'></i></div>").appendTo(this.yearPanel);
                $closed.click(function () {
                    _this.yearPanel.hide();
                    return false;
                });
            }
            var startYear = year - 12;
            var help = 22, txt, $it;
            while (help > 0) {
                if (help === 22) {
                    txt = "<i style='font-size:16px;color:#A0BFDE' class='fa fa-angle-double-left'></i>";
                    $it = $("<div class='k_box_size' style='float:left;line-height:20px;padding:5px 5px;cursor:pointer;width:43px;text-align:center;'>" + txt + "</div>").appendTo(this.yearPanel);
                    $it.on("click", { _this: this }, this._yearOnclick);
                }
                txt = startYear;
                $it = $("<div class='k_box_size _year_num' style='float:left;line-height:20px;padding:5px 5px;cursor:pointer;width:43px;text-align:center;'>" + txt + "</div>").appendTo(this.yearPanel);
                if (txt === year) {
                    $it.addClass("actived");
                }
                $it.on("click", { _this: this }, this._yearOnclick);
                if (help === 1) {
                    txt = "<i style='font-size:16px;color:#A0BFDE' class='fa fa-angle-double-right'></i>";
                    $it = $("<div class='k_box_size' style='float:left;line-height:20px;padding:5px 5px;cursor:pointer;width:43px;text-align:center;'>" + txt + "</div>").appendTo(this.yearPanel);
                    $it.on("click", { _this: this }, this._yearOnclick);
                }
                help--;
                startYear++;
            }
            if (append) {
                this.yearPanel.appendTo(this.jqObj);
            }
        },
        /**
         * 月模式下用
         * **/
        _activeMonthUi: function (month) {
            this.monthPanel.children().each(function () {
                var $m = $(this);
                if (month === parseInt($m.text())) {
                    $m.addClass("actived");
                } else {
                    $m.removeClass("actived");
                }
            });
        },
        /**月点击事件**/
        _monthOnclick: function (e) {
            var _this = e.data._this;
            var $t = $(this);
            var month = parseInt($t.text());
            _this.month = month;
            var newDate = _this._var2Date();
            if (_this._beforeChange(newDate)) {
                if (_this.isMonthStyle) {//月模式
                    $t.addClass("actived").siblings().removeClass("actived");
                    if (_this.opts.clickHide) {
                        _this.hide();
                    }
                }
                _this._setCurrentDate(newDate);
                _this.rebuildDaysUi();
                _this.updateYearAndMonthUi(_this.currentDate);
                _this.update2target(_this.currentDate);
                _this._hideMonthPanel();

            }
            return false;
        },
        _hideMonthPanel: function () {
            if (!this.isMonthStyle && this.monthPanel) {
                this.monthPanel.hide(120);
            }
        },
        /***
         * 月选择列表
         * **/
        _createMonthOpts: function () {
            var _this = this;
            if (!this.monthPanel) {
                this.monthPanel = $("<div class='k_box_size clearfix k_calendar_ym_panel' style='padding-bottom:4px; padding-top:8px;padding-left: 18px; position: absolute; top: 30px; left: 0px; z-index: 2100000000; width: 100%; background: rgb(255, 255, 255);'></div>").appendTo(this.jqObj);
                var i = 1, txt, $it;
                while (i < 13) {
                    txt = i;
                    if (i < 10) {
                        txt = "0" + i;
                    }
                    $it = $("<div style='float:left;line-height:32px;padding:5px 5px;cursor:pointer;width:45px;text-align:center;'>" + txt + "</div>").appendTo(this.monthPanel);
                    if (i === this.month) {
                        $it.addClass("actived");
                    }
                    $it.on("click", { _this: this }, this._monthOnclick);
                    i++;
                }
                if (!this.isMonthStyle) {
                    this.monthPanel.addClass("k_dropdown_shadow");
                    var $closed = $("<div style='position:absolute;top:-2px;right:5px;width:12px;height:12px;line-height:12px;text-align:center;cursor:pointer;'><i class='fa fa-cancel-2' style='font-size:14px;color:#AAAAB4'></i></div>").appendTo(this.monthPanel);
                    $closed.click(function () {
                        _this.monthPanel.hide();
                        return false;
                    });
                }
            } else {
                this.monthPanel.show();
                this.monthPanel.children().each(function () {
                    var $s = $(this);
                    if (parseInt($s.text()) === _this.month) {
                        $s.addClass("actived");
                    } else {
                        $s.removeClass("actived");
                    }
                });
            }
        },
        /**底部工具栏按钮***/
        createTools: function () {
            var _this = this;
            var clickFn = function () {
                var $t = $(this);
                if (_this.yearPanel) {
                    _this.yearPanel.hide();
                }
                if (!_this.isMonthStyle && _this.monthPanel) {
                    _this.monthPanel.hide();
                }
                if ($t.hasClass("002")) {
                    var now = new Date();
                    _this.year = now.getFullYear();
                    _this.month = now.getMonth() + 1;
                    _this.day = now.getDate();
                    _this.hour = now.getHours();
                    _this.minutes = now.getMinutes();
                    _this.seconds = now.getSeconds();
                    var newDate = _this._var2Date();
                    if (_this._beforeChange(newDate)) {
                        _this._setCurrentDate(newDate);
                        _this.rebuildDaysUi();
                        _this.updateYearAndMonthUi(_this.currentDate);
                        _this.update2target(_this.currentDate);
                        if (_this.isMonthStyle) {
                            _this._activeMonthUi(_this.month);
                        }
                        if (_this.opts.clickHide) {
                            _this.hide();
                        }
                    }
                } else if ($t.hasClass("003")) {
                    _this.target.val("");
                    _this.daysPanel.children().removeClass("activted");
                } else {
                    _this.hide();
                }
                return false;
            };
            var b1 = $("<div class='002'>" + this.config.now + "</div>").appendTo(this.toolPanel).click(clickFn);
            var b2 = $("<div class='003'>" + this.config.clear + "</div>").appendTo(this.toolPanel).click(clickFn);
            if(this.opts.fixed){
                b1.width(99);
                b2.width(99);
            }else{
                $("<div class='004'>" + this.config.close + "</div>").appendTo(this.toolPanel).click(clickFn);
            }
        },
        _getStrTime: function () {
            var h = this.hour;
            var m = this.minutes;
            var s = this.seconds;
            if (h < 10) { h = '0' + h; }
            if (m < 10) { m = '0' + m; }
            if (s < 10) { s = '0' + s; }
            return { h: h, m: m, s: s };
        },
        /**时分秒工具栏**/
        createTimeTools: function () {
            var _this = this;
            var onHclick = function () {                
                var $s = $(this);
                var v = $s.text();
                if (_this.userInput.attr("id") === "_k_cal_hour") {
                    _this.hour = parseInt(v);
                } else if (_this.userInput.attr("id") === "_k_cal_minu") {
                    _this.minutes = parseInt(v);
                } else {
                    _this.seconds = parseInt(v);
                }
                var newDate = _this._var2Date();
                if (_this._beforeChange(newDate)) {                    
                    _this.userInput.val(v);
                    _this._setCurrentDate(newDate);
                    _this.update2target(newDate);
                    $s.parent().hide();
                }
                return false;
            };
            var onClickFn = function () {
                var $t = $(this);               
                if (_this.yearPanel) {
                    _this.yearPanel.hide();
                }
                if (_this.monthPanel && !_this.isMonthStyle) {
                    _this.monthPanel.hide();
                }
                var i, len, $closed;
                if ($t.attr("id") === "_k_cal_hour") {
                    if (_this.mmItsPanel) {
                        _this.mmItsPanel.hide();
                    }
                    if (!_this.hourItsPanel) {
                        _this.hourItsPanel = $("<div class='k_box_size clearfix k_calendar_hours_panel k_dropdown_shadow' style='padding-left: 12px; position: absolute; top: 30px; left: 0px; z-index: 2112000000; width: 100%; background: rgb(255, 255, 255);'></div>");
                        for (i = 0; i < 24; i++) {
                            $("<span>" + (i < 10 ? '0' + i : i) + "</span>").appendTo(_this.hourItsPanel).click(onHclick);
                        }
                        _this.hourItsPanel.appendTo(_this.jqObj);
                        $closed = $("<div style='position:absolute;top:-2px;right:5px;width:12px;height:12px;line-height:12px;text-align:center;cursor:pointer;'><i class='fa fa-cancel-2' style='font-size:14px;color:#AAAAB4'></i></div>").appendTo(_this.hourItsPanel);
                        $closed.click(function () {
                            _this.hourItsPanel.hide();
                            return false;
                        });
                    } else {
                        if (_this.hourItsPanel.css("display") === "none") {
                            _this.hourItsPanel.show();
                        } else {
                            _this.hourItsPanel.hide();
                        }
                    }
                } else {
                    if (_this.hourItsPanel) {
                        _this.hourItsPanel.hide();
                    }
                    if (!_this.mmItsPanel) {
                        _this.mmItsPanel = $("<div class='k_box_size clearfix k_calendar_mm_panel k_dropdown_shadow' style='padding-top:6px;padding-left: 12px; position: absolute; top: 30px; left: 0px; z-index: 2112000000; width: 100%; background: rgb(255, 255, 255);'></div>");
                        for (i = 0; i < 60; i++) {
                            $("<span>" + (i < 10 ? '0' + i : i) + "</span>").appendTo(_this.mmItsPanel).click(onHclick);
                        }
                        _this.mmItsPanel.appendTo(_this.jqObj);
                        $closed = $("<div style='position:absolute;top:-2px;right:5px;width:12px;height:12px;line-height:12px;text-align:center;cursor:pointer;'><i class='fa fa-cancel-2' style='font-size:14px;color:#AAAAB4'></i></div>").appendTo(_this.mmItsPanel);
                        $closed.click(function () {
                            _this.mmItsPanel.hide();
                            return false;
                        });
                    } else {
                        if (_this.mmItsPanel.css("display") === "none") {
                            _this.mmItsPanel.show();
                        } else {
                            _this.mmItsPanel.hide();
                        }
                    }
                }
                _this.userInput = $t;
                return false;
            };
            var s = this._getStrTime();
            this.$hour = $("<input readonly='readonly' style='border:1px solid #CBD8EA;width:30px;text-align:center;' id='_k_cal_hour' value='" + s.h + "'/>").appendTo(this.timePanel).click(onClickFn);
            this.timePanel.append("<span>：</span>");
            this.$minutes = $("<input  readonly='readonly' style='border:1px solid #CBD8EA;width:30px;text-align:center' id='_k_cal_minu' value='" + s.m + "'/>").appendTo(this.timePanel).click(onClickFn);
            if (this.isSecondStyle) {
                this.timePanel.append("<span>：</span>");
                this.$seconds = $("<input  readonly='readonly' style='border:1px solid #CBD8EA;width:30px;text-align:center' id='_k_cal_secs' value='" + s.s + "'/>").appendTo(this.timePanel).click(onClickFn);
            }
        },
        /**
         * 更新时分秒 下拉框
         * ***/
        _updateMinAndCec: function () {
            var s = this._getStrTime();
            if (this.$hour) {
                this.$hour.val(s.h);
            }
            if (this.$minutes) {
                this.$minutes.val(s.m);
            }
            if (this.$seconds) {
                this.$seconds.val(s.s);
            }
        },
        /**
         * 根据newDate新时间重建列表,
         * ****/
        rebuildDaysUi: function (newDate) {
            if (newDate) {
                this.year = newDate.getFullYear();
                this.month = newDate.getMonth() + 1;
            }
            var startDate = this._getStartDate();
            var day, month, tmpStr;
            var one = this.daysPanel.children().first();
            while (one.length > 0) {
                day = startDate.getDate();
                month = startDate.getMonth() + 1;
                tmpStr = startDate.format("yyyy-MM-dd");
                if (month !== this.month) {
                    one.addClass("day_dull").removeClass("activted").attr("title", tmpStr);
                } else {
                    one.removeClass("day_dull").removeAttr("title");
                    if (day === this.day) {
                        one.addClass("activted");
                    } else {
                        one.removeClass("activted");
                    }
                }
                one.text(day).attr("t", tmpStr);
                startDate.setDate(startDate.getDate() + 1);
                one = one.next();
            }
        },
        /**
         * 根据新时间更新年月ui
         * ***/
        updateYearAndMonthUi: function (newDate) {
            var year = newDate.getFullYear();
            var monthIdx = newDate.getMonth();
            var month = this.config.monthArray[monthIdx];
            this.headerPanel.children("._cur_year").text(year).next().next().text(month);
        },
        /**
         * 将date根据 config.fmt格式化后设置到target中
         * isCancel 多选场景下，是否是取消
         * ***/
        update2target: function (date, isCancel) {
            var strValue = date.format(this.opts.fmt);
            this.target.val(strValue);
            console.log("update2target >>>");
            if(this.onWatcher){//配合双向联动使用
                this.onWatcher.call(this);
            }
        },
        /***
         * 根据this.year,this.month 获取星期日开始时间
         * ***/
        _getStartDate: function () {
            var curMonthIdx = this.month - 1;
            var curMonthFisrtDate = new Date(this.year, curMonthIdx, 1);
            var weekDay = curMonthFisrtDate.getDay();
            var startDate = new Date(curMonthFisrtDate);
            while (weekDay > 0) {
                startDate.setDate(startDate.getDate() - 1);
                weekDay--;
            }
            return startDate;
        },
        _dayOnclick: function (e) {
            var _this = e.data._this;
            var $t = $(this);
            var arr = $t.attr("t").split("-");
            _this.year = parseInt(arr[0]);
            _this.month = parseInt(arr[1]);
            _this.day = parseInt(arr[2]);
            var newDate = _this._var2Date();
            if (_this._beforeChange(newDate)) {
                _this._setCurrentDate(newDate);
                _this.updateYearAndMonthUi(_this.currentDate);
                _this.update2target(_this.currentDate);
                $t.addClass("activted").siblings().removeClass("activted");
                if (_this.opts.clickHide) {
                    _this.hide();
                }
            }
            return false;
        },
        /**
         * 创建天日期列表
         * ****/
        createDays: function () {
            var curMonthIdx = this.month - 1;
            var startDate = this._getStartDate();
            var count = 42, tmpStr, tmpSpan, tmpDay, tmpMonth;
            while (count > 0) {
                tmpStr = startDate.format("yyyy-MM-dd");
                tmpDay = startDate.getDate();
                tmpMonth = startDate.getMonth();
                tmpSpan = $("<span t='" + tmpStr + "'>" + tmpDay + "</span>").appendTo(this.daysPanel);
                if (curMonthIdx !== tmpMonth) {
                    tmpSpan.addClass("day_dull").attr("title", tmpStr);
                } else {
                    if (tmpDay === this.day) {
                        tmpSpan.addClass("activted");
                    }
                }
                tmpSpan.on("click", { _this: this }, this._dayOnclick);
                startDate.setDate(startDate.getDate() + 1);
                count--;
            }
        },
        /***
         * 将用户输入的时间字符串转为Date对象
         * ***/
        _txt2Date: function (txtDate) {
            if (txtDate === "") {
                return undefined;
            }
            var m = txtDate.match(/^(\s*\d{4}\s*)(-|\/)\s*(0?[1-9]|1[0-2]\s*)(-|\/)?(\s*[012]?[0-9]|3[01]\s*)?\s*([01]?[0-9]|2[0-4]\s*)?:?(\s*[012345]?[0-9]|\s*)?:?(\s*[012345]?[0-9]\s*)?$/);
            if (!m[1] && !m[3]) {
                return undefined;
            }
            var year = parseInt(m[1]),
                month = parseInt(m[3]) - 1,
                day = 1,
                hour = 0,
                minutes = 0,
                seconds = 0;

            if (m[5]) {
                day = parseInt(m[5]);
            }
            if (m[6]) {
                hour = parseInt(m[6]);
            }
            if (m[7]) {
                minutes = parseInt(m[7]);
            }
            if (m[8]) {
                seconds = parseInt(m[8]);
            }
            var date = new Date(year, month, day, hour, minutes, seconds);
            return date;
        },
        /***
         * 将date对象提取year、month、day设置到变量this.year,this.month......
         * ***/
        _setVarByDate: function (date) {
            this.year = date.getFullYear();
            this.month = date.getMonth() + 1;
            this.day = date.getDate();
            this.hour = date.getHours();
            this.minutes = date.getMinutes();
            this.seconds = date.getSeconds();
        },
        /***
         * this.year,this.month 转为 date对象返回
         * ***/
        _var2Date: function () {
            //存在bug，this.day,29,30,31可能是不存在的，需要修正
            try {
                var tmpDate = new Date(this.year, this.month, 0);
                var maxDay = tmpDate.getDate();
                if (this.day > maxDay) {
                    this.day = maxDay;
                }
                var date = new Date(this.year, this.month - 1, this.day, this.hour, this.minutes, this.seconds);
                return date;
            } catch (ex) {
                $B.error(this.config.error);
                return undefined;
            }
            return date;
        },
        /**
         * 将date参数设置到currentDate
         * ***/
        _setCurrentDate: function (date) {
            this.currentDate = date;
        },
        /***
         * 将newDate更新至 currentDate及year\month\day变量
         * ***/
        _updateVar: function (newDate) {
            this._setCurrentDate(newDate);
            this._setVarByDate(newDate);
        },
        setPositionByTimer: function () {
            var _this = this;
            if (_this.t1) {
                var t2 = new Date();
                if ((t2.getTime() - _this.t1.getTime()) > 1000) {
                    _this.setPosition();
                    _this.t1 = t2;
                }
            } else {
                _this.t1 = new Date();
            }
            clearTimeout(this.positionTimer);
            this.positionTimer = setTimeout(function () {
                _this.setPosition();
            }, 600);
        },
        setPosition: function () {
            var ofs = this.target.offset();
            var css, height;
            if (this._isTopPosition()) {
                height = this._getPanelHeight();
                css = { top: ofs.top - height, left: ofs.left };
            } else {
                height = this.target.outerHeight() - 1;
                css = { top: ofs.top + height, left: ofs.left };
            }
            this.jqObj.css(css);
        },
        slideToggle: function () {
            if (this.jqObj.css("display") === "none") {
                this.show();
            } else {
                this.hide();
            }
        },
        _getPanelHeight: function () {
            var height = 276;
            if (this.isMonthStyle || this.isDayStyle) {
                height = 250;
            }
            return height;
        },
        _isTopPosition: function () {
            var bodyHeight = _getBody().height();
            var h = this.target.offset().top + this.target.outerHeight() + this._getPanelHeight();
            if ((h - bodyHeight) > 0) {
                return true;
            }
            return false;
        },
        hide: function () {
            if (this.opts.fixed) {
                return;
            }
            if (this.hourItsPanel) {
                this.hourItsPanel.hide();
            }
            if (this.mmItsPanel) {
                this.mmItsPanel.hide();
            }
            if (this._isTopPosition()) {
                this.jqObj.hide();
            } else {
                this.jqObj.slideUp(200);
            }
            if (this.yearPanel) {//恢复ui
                this.yearPanel.hide();
            }
            this._hideMonthPanel();
        },
        show: function () {
            if (this.opts.fixed) {
                return;
            }
            this.setPosition();
            if (this._isTopPosition()) {
                this.jqObj.show();
            } else {
                this.jqObj.slideDown(200);
            }
        },
        /***
         * 设置时间 date = New Date / yyyy-MM-dd 
         * ***/
        setValue: function (date) {
            var newDate;
            if (typeof date === "string") {
                newDate = this._txt2Date(date);
            } else {
                newDate = date;
            }
            this._setCurrentDate(newDate);
            this._setVarByDate(newDate);
            this.rebuildDaysUi();
            this.updateYearAndMonthUi(this.currentDate);
            this._updateMinAndCec();
            if (!this.opts.mutil) {
                this.update2target(this.currentDate);
            }
        },
        setTarget: function (target, isInit) {
            if (this.target && this.target[0] !== target[0]) {
                if (this.jqObj.css("display") !== "none") {
                    this.jqObj.hide();
                }
            }
            this.target = target;
            this._bindInputEvents();
            this._initValue(isInit);
            this.rebuildDaysUi();
            this.updateYearAndMonthUi(this.currentDate);
            this._updateMinAndCec();
        }
    };
    $B["Calendar"] = MyDate;
    return MyDate;
}));